How can i set time out condition in the timer? Duplicated : https://forum.qt.io/topic/138913/qtimer-make-traitement-out-of-for-loop
-
Hi everyone;
In my case i want to send the first 5 lines (can frames) of table sequentially with a for loop: but there is an extra condition when he find the line of +50 ( if (PayloadData_R=="F12B")) to be sended, he have to make a traitement inside the timer that takes 6 second inside the timer .he ignored it then get back to it after sending the next line !for(int i=0; i< selection.count(); i++) { ... QString PayloadData_R = m_ui->Table_CSV->model()->data(m_ui->Table_CSV->model()->index(b,1)).toString(); ... //sending data in selected row to do make a sending method if (PayloadData_R=="F12B") //like the Command in the line 4 and 5 in the table { // sending "F12B" AND GET "FF" //traitement inside the timer that sends "F6....10" get "FF" //then send "F504" and gets "FD0F5CD42" QTimer::singleShot(6000, [=](){ qDebug()<<"Timer on do something after 6 second..."; // i want to set a time out condition here });//timer ends here }//end if(PayloadData_R=="F12B") //*******// else if (m_canDevice) { ...//traitement sends commands of table in lines 1,2 and 3 }//end else if(m_canDevice) }//end for loop
-
@imene said in How can i set time out condition in the timer? Duplicated : https://forum.qt.io/topic/138913/qtimer-make-traitement-out-of-for-loop:
In my case i want to send the first 5 lines (can frames) of table sequentially with a for loop: but there is an extra condition when he find the line of +50 ( if (PayloadData_R=="F12B")) to be sended, he have to make a traitement inside the timer that takes 6 second inside the timer .he ignored it then get back to it after sending the next line !
Your english seems as bad as mine :)
The asynchronous nature of Qt prevents you from blocking the eventloop.
In such situation, I'm using such algo structure:(pseudo code)
void proceedNextStep() // slot { // do step work // if no more step return; // proceed next step QTimer::singleShot(100,this, proceedNextStep); }
You may have to create some variables to register the state of the current operation.
If at some point you have to wait 6s, you call next step with that delay:
QTimer::singleShot(6000,this, proceedNextStep);
and set some flag as:
currentSate=LongDelayTimeOut;
that you can test on next call to proceedNextStep()Just some ideas, of course it needs some further thinking to fit your use case.
-
Thanks @mpergand i'm trying my best
Actually, i want my code to run the traitement inside Qtimer befor it moves to the next if condition.
Could i put the traitement inside this proceed ?void proceedNextStep() // slot { // do step work // if no more step return; // proceed next step QTimer::singleShot(6000,this, proceedNextStep); }
and from where i get "LongDelayTimeOut" is it known by Qt ?
-
@imene said in How can i set time out condition in the timer? Duplicated : https://forum.qt.io/topic/138913/qtimer-make-traitement-out-of-for-loop:
and from where i get "LongDelayTimeOut" is it known by Qt ?
You have to replace the for loop with a counter and to define the different states you need:
enum { Proceed_next, LongDelayTimeOut, ... }
as well as an instance variable to store the current operation status:
if(_currentState==LongDelayTimeOut) { // long delay ending } else if(_currentState==Proceed_next) { _counter++; // get next payload if (PayloadData_R=="F12B") { _currentState=LongDelayTimeOut; QTimer::singleShot(6000, this, proceedNextStep); return; } // next payload _currentState=Proceed_next; // default state QTimer::singleShot(100,this, proceedNextStep); } }
Keep in mind that you need to know what to do each time proceedNext is call, so you need to carefuly define the different states of the current operation.
-
-
@imene said in How can i set time out condition in the timer? Duplicated : https://forum.qt.io/topic/138913/qtimer-make-traitement-out-of-for-loop:
while(_counter!=0){_counter--}
You can't have a loop, neither for nor while.
To eliminate the counter variable, you can put all the process informations you have to send in a queue (ex: QQueue) and call nextstep untill the queue is empty.QQueue _proceedInfo; // instance variable ... void proceedNextStep() // slot { if(_processInfo.empty()) return; // no more process // do step work QString info=_processInfo.dequeue(); if(info=="F12B")) // special case { QTimer::singleShot(6000,this, [this]() { // long delay timeout ... // next step QTimer::singleShot(0,this, proceedNextStep); }); return; } // do other process ... // proceed next step QTimer::singleShot(0,this, proceedNextStep); }
-
@imene said in How can i set time out condition in the timer? Duplicated : https://forum.qt.io/topic/138913/qtimer-make-traitement-out-of-for-loop:
for(int i=0; i< selection.count(); i++)
@mpergand can i fill QQueue _proceedInfo this way ?
QQueue _proceedInfo; for(int i=0; i< selection.count(); i++) { _proceedInfo=i; } void proceedNextStep() // slot { if(_processInfo.empty()) return; // no more process // do step work QString info=_processInfo.dequeue(); if(info=="F12B")) // special case { QTimer::singleShot(6000,this, [this]() { // long delay timeout ... // next step QTimer::singleShot(0,this, proceedNextStep); }); return; } // do other process ... // proceed next step QTimer::singleShot(0,this, proceedNextStep); }
and look what i get here:
-
@imene said in How can i set time out condition in the timer? Duplicated : https://forum.qt.io/topic/138913/qtimer-make-traitement-out-of-for-loop:
can i fill QQueue _proceedInfo this way ?
Please read documentation: https://doc.qt.io/qt-6/qqueue.html
To add elements to the queue you call enqueue() as shown there.Regarding error: what you are doing is wrong. When you call singleShot you do NOT call the member function but pass its address:
QTimer::singleShot(100, this, &MainWindow::processStep);
-
@imene said in How can i set time out condition in the timer? Duplicated : https://forum.qt.io/topic/138913/qtimer-make-traitement-out-of-for-loop:
can i fill QQueue _proceedInfo this way ?
QQueue is a tempate class, see the doc.
try: QTimer::singleShot(0,this, SLOT(proceedNextStep));
Remember what i write is pseudo code. -
@jsulm
i found this code here https://doc.qt.io/qt-6/qqueue.htmlQQueue<int> queue; queue.enqueue(1); queue.enqueue(2); queue.enqueue(3);
i fixe it this way:
QQueue<int> _proceedInfo; for(int i=0; i< selection.count(); i++) { _proceedInfo.enqueue(i); }
-
@mpergand in this case in your code :
QQueue _proceedInfo; // instance variable ... void proceedNextStep() // slot { if(_processInfo.empty()) return; // no more process // do step work QString info=_processInfo.dequeue(); if(info=="F12B")) // special case { QTimer::singleShot(6000,this, [this]() { // long delay timeout ... // next step QTimer::singleShot(0,this, proceedNextStep); }); return; } // do other process ... // proceed next step QTimer::singleShot(0,this, proceedNextStep); }
No need for enum variable ? they doesn't exist here ?
-
@mpergand is this code have to be inside void proceedNextStep(){...} ?
if(_currentState==LongDelayTimeOut) { // long delay ending } else if(_currentState==Proceed_next) { _counter++; // get next payload if (PayloadData_R=="F12B") { _currentState=LongDelayTimeOut; QTimer::singleShot(6000, this, proceedNextStep); return; } // next payload _currentState=Proceed_next; // default state QTimer::singleShot(100,this, proceedNextStep); } }
-
@imene said in How can i set time out condition in the timer? Duplicated : https://forum.qt.io/topic/138913/qtimer-make-traitement-out-of-for-loop:
No need for enum variable ?
Yes if it is all you have to do.
I still don't understand why you want to store number instead of the data you really need:
QString PayloadData_R = m_ui->Table_CSV->model()->data(m_ui->Table_CSV->model()->index(b,1)).toString();
Put that string directly in the queue.
-
@mpergand Because i need "b" inside index(b,1)
i get it this way:for(int i=0; i< selection.count(); i++) { QModelIndex ind = selection.at(i);//at returns item at the index position i qDebug() << "QModelIndex ind = selection.at(i);" << ind; int a= ind.column(); //Returns the column this model index refers to qDebug() << "a=" << a; int b= ind.row(); //Returns the row this model index refers to qDebug() << "b=" << b; //indice ligne //getting data from selected row QString PayloadData_R = m_ui->Table_CSV->model()->data(m_ui->Table_CSV->model()->index(b,1)).toString(); qDebug() <<"PayloadData_R sendrow="<<PayloadData_R;
-
The idea is to put the data you need in the queue before calling proceedNext:
for(int i=0; i< selection.count(); i++) { QModelIndex ind = selection.at(i);//at returns item at the index position i // bla bla _proceedInfo.enqueue(PayloadData_R); } // start sending data proceedNext();