I needed a timer that fires in intervals for a given duration when e.g. a button is pressed. The button can be pressed several times thus I thought it would be easiest to create a new timer for each button press and the timer destroys itself when its duration passed. I wrote this...
Interface:
// timerhandler.h
class TimerHandler {
public:
virtual void processTimer()=0; // callback
void startNewTimer(int interval,int duration);
virtual ~TimerHandler(){}
};
//timerhandler.cpp
#include "timerhandler.h"
#include "mytimer.h"
void TimerHandler::startNewTimer(int interval,int duration){
new MyTimer(this,interval,duration);
}
Usage: MainWindow inherits TimerHandler
//MainWindow.cpp
void MainWindow::on_pushButton_start_clicked() { this->startNewTimer(100,2000); }
void MainWindow::processTimer() { std::cout << "TIMER" << std::endl; }
Implementation:
//mytimer.h
#include <QObject>
#include <QTimer>
class TimerHandler;
class MyTimer : public QObject {
Q_OBJECT
public:
friend class TimerHandler;
private:
TimerHandler* th;
QTimer* timer;
MyTimer(){};
MyTimer(TimerHandler* th,int interval,int duration);
~MyTimer();
public slots:
void commitSuicide();
void on_timer_fired();
};
//mytimer.cpp
MyTimer::MyTimer(TimerHandler* th,int interval,int duration) : th(th) {
timer = new QTimer(this);
connect(timer, SIGNAL(timeout()), this, SLOT(on_timer_fired()));
timer->start(interval);
QTimer::singleShot(duration,this,SLOT(commitSuicide()));
}
MyTimer::~MyTimer(){ delete timer; }
void MyTimer::commitSuicide(){ delete this; }
void MyTimer::on_timer_fired(){ th->processTimer(); }
...it works, but I wonder if there is an easier way (less code) and it is horribly inflexible. I am a bit stuck when I want to change the code to allow different callbacks (that take different parameters).
I first tried a virtual slot as interface. I think it would work somehow, but when TimerHandler
inherits QOject
, then my MainWindow
inherits QObject
twice and I could not get it running.
Also if there is anything else that I can/should fix please let me know.