How to create some Timers at run time and handle them?
-
@Jamshid said in How to create some Timers at run time and handle them?:
So using QTimer with specific slots won't work.
There is always QObject::sender() where you can see where the signal is coming from. Apart from this why not storing all created timers in a QVector/QHash/whatever so you can access them later on?
@Christian-Ehrlicher I'm trying sender(), I can store created timers in a vector and connect all created timers' timeout signal to one slot, my problem is this how to determine in that slot which timer timed out. I think QObject::sender() will help. let me try it.
-
@Christian-Ehrlicher I'm trying sender(), I can store created timers in a vector and connect all created timers' timeout signal to one slot, my problem is this how to determine in that slot which timer timed out. I think QObject::sender() will help. let me try it.
@Jamshid I would actually suggest to use a lambda over the sender() approach
for(int i(0); i <10; i++){ QTimer *t = new QTimer(this); connect(t, &QTimer::timeout, this, [=]()->void{timerSlot(i);}); m_timers.append(t); } ... public slots: void timerSlot(int timeId);
-
@Christian-Ehrlicher I'm trying sender(), I can store created timers in a vector and connect all created timers' timeout signal to one slot, my problem is this how to determine in that slot which timer timed out. I think QObject::sender() will help. let me try it.
@Jamshid
For a slot functionsender
should give you which timer. My understanding (untested!) is that if you use a lambda you do not get asender
. But then @J-Hilk is, I think, offering a lambda which passes thetimerId
as a parameter for you. Both sound like they would work. -
@Jamshid
For a slot functionsender
should give you which timer. My understanding (untested!) is that if you use a lambda you do not get asender
. But then @J-Hilk is, I think, offering a lambda which passes thetimerId
as a parameter for you. Both sound like they would work.@JonB well, yes, we originally talked about identifying the timer that called the slot, what better way than an int ? ๐
Well, If one is more interested in the Timer Object....
for(int i(0); i <10; i++){ QTimer *t = new QTimer(this); connect(t, &QTimer::timeout, this, [=]()->void{timerSlot(t);}); m_timers.append(t); } ... public slots: void timerSlot(QTimer *timer);
-
@Jamshid I would actually suggest to use a lambda over the sender() approach
for(int i(0); i <10; i++){ QTimer *t = new QTimer(this); connect(t, &QTimer::timeout, this, [=]()->void{timerSlot(i);}); m_timers.append(t); } ... public slots: void timerSlot(int timeId);
@J-Hilk I test this code, It only passes the last timer ID.
if (!List.contains(str)) { // Start timer timer = new QTimer(this); timer->setInterval(200); timer->start(); connect(timer, &QTimer::timeout, this, [=]()->void{integrityTimersEvent(timer->timerId());}); // timersList.append(timer); timersIDList.append(timer->timerId()); }
void FrameProcessor::integrityTimersEvent(int timerID) { qDebug() << "integrityTimersEvent => Timer ID:" << timerID; }
Am I doing it right way?
-
@J-Hilk I test this code, It only passes the last timer ID.
if (!List.contains(str)) { // Start timer timer = new QTimer(this); timer->setInterval(200); timer->start(); connect(timer, &QTimer::timeout, this, [=]()->void{integrityTimersEvent(timer->timerId());}); // timersList.append(timer); timersIDList.append(timer->timerId()); }
void FrameProcessor::integrityTimersEvent(int timerID) { qDebug() << "integrityTimersEvent => Timer ID:" << timerID; }
Am I doing it right way?
@Jamshid , @J-Hilk
It only passes the last timer ID.
This is just the kind of behaviour I found when playing with lambdas (which is why I don't much like them, let's not go there)! To get it right, I believe, you must pass the
timer->timerID()
, or the wholetimer
, as a parameter to the lambda. Not sure of the C++ (I'm Python) syntax, but I think it must go inside the()
you have...EDIT Oh well, since @J-Hilk shows it works below, I must be mistaken, sorry.... I had this kind of problem with Python lambdas, they must not directly access a changing value in the caller in their body code, instead the caller must pass that as a parameter....
-
@J-Hilk I test this code, It only passes the last timer ID.
if (!List.contains(str)) { // Start timer timer = new QTimer(this); timer->setInterval(200); timer->start(); connect(timer, &QTimer::timeout, this, [=]()->void{integrityTimersEvent(timer->timerId());}); // timersList.append(timer); timersIDList.append(timer->timerId()); }
void FrameProcessor::integrityTimersEvent(int timerID) { qDebug() << "integrityTimersEvent => Timer ID:" << timerID; }
Am I doing it right way?
@Jamshid
should work fine,take a look at the example I made:
int MainWindow::count = 0; MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow) { for(int i(0); i <10; i++){ QTimer *t = new QTimer(this); connect(t, &QTimer::timeout, this, [=]()->void{timerSlot(t->timerId());}); m_timers.append(t); t->start(100); } } void MainWindow::timerSlot(int timerId) { qDebug() << timerId; qDebug() << Q_FUNC_INFO << count++; }
which results in the correct call of:
1 void MainWindow::timerSlot(int) 0 2 void MainWindow::timerSlot(int) 1 3 void MainWindow::timerSlot(int) 2 4 void MainWindow::timerSlot(int) 3 5 void MainWindow::timerSlot(int) 4 6 void MainWindow::timerSlot(int) 5 7 void MainWindow::timerSlot(int) 6 8 void MainWindow::timerSlot(int) 7 9 void MainWindow::timerSlot(int) 8 10 void MainWindow::timerSlot(int) 9 1 void MainWindow::timerSlot(int) 10 2 void MainWindow::timerSlot(int) 11 3 void MainWindow::timerSlot(int) 12 4 void MainWindow::timerSlot(int) 13 5 void MainWindow::timerSlot(int) 14 6 void MainWindow::timerSlot(int) 15 7 void MainWindow::timerSlot(int) 16 8 void MainWindow::timerSlot(int) 17 9 void MainWindow::timerSlot(int) 18 10 void MainWindow::timerSlot(int) 19 1 void MainWindow::timerSlot(int) 20 2 void MainWindow::timerSlot(int) 21 3 void MainWindow::timerSlot(int) 22 4 void MainWindow::timerSlot(int) 23 5 void MainWindow::timerSlot(int) 24 6 void MainWindow::timerSlot(int) 25 7 void MainWindow::timerSlot(int) 26 8 void MainWindow::timerSlot(int) 27 9 void MainWindow::timerSlot(int) 28 10 void MainWindow::timerSlot(int) 29 1 void MainWindow::timerSlot(int) 30 2 void MainWindow::timerSlot(int) 31 3 void MainWindow::timerSlot(int) 32 4 void MainWindow::timerSlot(int) 33 5 void MainWindow::timerSlot(int) 34 6 void MainWindow::timerSlot(int) 35 7 void MainWindow::timerSlot(int) 36 8 void MainWindow::timerSlot(int) 37 9 void MainWindow::timerSlot(int) 38 10 void MainWindow::timerSlot(int) 39 1 void MainWindow::timerSlot(int) 40 2 void MainWindow::timerSlot(int) 41 3 void MainWindow::timerSlot(int) 42 4 void MainWindow::timerSlot(int) 43 5 void MainWindow::timerSlot(int) 44 6 void MainWindow::timerSlot(int) 45 7 void MainWindow::timerSlot(int) 46 8 void MainWindow::timerSlot(int) 47 9 void MainWindow::timerSlot(int) 48 10 void MainWindow::timerSlot(int) 49 1 void MainWindow::timerSlot(int) 50
edit: @JonB
the [=] is a "capture everything by copy" indicator. So no explicit capture of the id should be required -
@J-Hilk I test this code, It only passes the last timer ID.
if (!List.contains(str)) { // Start timer timer = new QTimer(this); timer->setInterval(200); timer->start(); connect(timer, &QTimer::timeout, this, [=]()->void{integrityTimersEvent(timer->timerId());}); // timersList.append(timer); timersIDList.append(timer->timerId()); }
void FrameProcessor::integrityTimersEvent(int timerID) { qDebug() << "integrityTimersEvent => Timer ID:" << timerID; }
Am I doing it right way?
@Jamshid said in How to create some Timers at run time and handle them?:
Am I doing it right way?
I would guess timer is a member variable, then yes you're doing it wrong. You copy the whole context ( [=]) and therefore the access inside the lambda is 'this->timer'
-
@J-Hilk I test this code, It only passes the last timer ID.
if (!List.contains(str)) { // Start timer timer = new QTimer(this); timer->setInterval(200); timer->start(); connect(timer, &QTimer::timeout, this, [=]()->void{integrityTimersEvent(timer->timerId());}); // timersList.append(timer); timersIDList.append(timer->timerId()); }
void FrameProcessor::integrityTimersEvent(int timerID) { qDebug() << "integrityTimersEvent => Timer ID:" << timerID; }
Am I doing it right way?
@Jamshid
actually thistimer = new QTimer(this); timer->setInterval(200); timer->start(); connect(timer, &QTimer::timeout, this, [=]()->void{integrityTimersEvent(timer->timerId());});
is referencing the member variable
try the following:
QTimer *t = new QTimer(this); t->setInterval(200); t->start(); connect(t, &QTimer::timeout, this, [=]()->void{integrityTimersEvent(t->timerId());}); timer = t;
-
@Jamshid
actually thistimer = new QTimer(this); timer->setInterval(200); timer->start(); connect(timer, &QTimer::timeout, this, [=]()->void{integrityTimersEvent(timer->timerId());});
is referencing the member variable
try the following:
QTimer *t = new QTimer(this); t->setInterval(200); t->start(); connect(t, &QTimer::timeout, this, [=]()->void{integrityTimersEvent(t->timerId());}); timer = t;