Solved How to create some Timers at run time and handle them?
-
@Jamshid Unless someone more experienced have other way I'd go somewhere along that way:
- derive from QTimer and include just one field: id, lets assume it is qint32 or something and name teh class here QTimer2;
- create QHash<int,QTimer2*>
And store the pointers and position that is equal to field id in QTimer2. This way you'll be able to examine which instance called and connect signals/slots.
Mind you, I don't find this solution very elegant. This is only rough idea and there might be better one.
-
@mrjj I don't know how many timers should I need in program, they are created with respect to input data.
-
@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?
-
@artwaw I'm new to Qt but I'll try it. Thanks.
-
@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);
-
-
@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);
-
@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?
-
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....
-
@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 -
@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'
-
@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;
-
@J-Hilk Thanks a lot, now it works, I'm new to Qt and this topic I think was a little bit advanced for me :)
-
Thank you all dear friends, that’s really kind of you.
Your help is so appreciated.