Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. How can i set time out condition in the timer? Duplicated : https://forum.qt.io/topic/138913/qtimer-make-traitement-out-of-for-loop
Forum Updated to NodeBB v4.3 + New Features

How can i set time out condition in the timer? Duplicated : https://forum.qt.io/topic/138913/qtimer-make-traitement-out-of-for-loop

Scheduled Pinned Locked Moved Unsolved General and Desktop
21 Posts 4 Posters 1.6k Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • I Offline
    I Offline
    imene
    wrote on last edited by imene
    #1

    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
    
    

    48710bd7-a31f-468e-b80e-d4b5d5e26f08-image.png

    JonBJ M 2 Replies Last reply
    0
    • I imene

      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
      
      

      48710bd7-a31f-468e-b80e-d4b5d5e26f08-image.png

      JonBJ Offline
      JonBJ Offline
      JonB
      wrote on last edited by
      #2

      @imene Duplicate https://forum.qt.io/topic/138913/qtimer-make-traitement-out-of-for-loop.

      1 Reply Last reply
      1
      • I imene

        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
        
        

        48710bd7-a31f-468e-b80e-d4b5d5e26f08-image.png

        M Offline
        M Offline
        mpergand
        wrote on last edited by
        #3

        @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.

        1 Reply Last reply
        1
        • I Offline
          I Offline
          imene
          wrote on last edited by
          #4

          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 ?

          M I 2 Replies Last reply
          0
          • I imene

            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 ?

            M Offline
            M Offline
            mpergand
            wrote on last edited by mpergand
            #5

            @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.

            I 1 Reply Last reply
            0
            • I Offline
              I Offline
              imene
              wrote on last edited by imene
              #6

              @mpergand is "_counter++" an integer ?
              in my case for(i=0, i< selection.count(), i++) so selection.count()=_counter?
              and what _currentState takes initially ?

              insteed of

              for(int i=0; i< selection.count(); i++)
              

              i will put

              while(_counter!=0){_counter--}
              
              M 1 Reply Last reply
              0
              • I imene

                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 ?

                I Offline
                I Offline
                imene
                wrote on last edited by
                #7

                @imene What do you mean with

                    // do step work
                    
                    // if no more step
                

                inside void proceedNextStep() {} ?

                1 Reply Last reply
                0
                • I imene

                  @mpergand is "_counter++" an integer ?
                  in my case for(i=0, i< selection.count(), i++) so selection.count()=_counter?
                  and what _currentState takes initially ?

                  insteed of

                  for(int i=0; i< selection.count(); i++)
                  

                  i will put

                  while(_counter!=0){_counter--}
                  
                  M Offline
                  M Offline
                  mpergand
                  wrote on last edited by
                  #8

                  @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);
                      }
                  
                  1 Reply Last reply
                  0
                  • I Offline
                    I Offline
                    imene
                    wrote on last edited by imene
                    #9

                    @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:
                    45c6c274-d091-4031-81a3-dba8af013621-image.png

                    jsulmJ M 2 Replies Last reply
                    0
                    • I imene

                      @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:
                      45c6c274-d091-4031-81a3-dba8af013621-image.png

                      jsulmJ Offline
                      jsulmJ Offline
                      jsulm
                      Lifetime Qt Champion
                      wrote on last edited by
                      #10

                      @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);
                      

                      https://forum.qt.io/topic/113070/qt-code-of-conduct

                      1 Reply Last reply
                      1
                      • I imene

                        @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:
                        45c6c274-d091-4031-81a3-dba8af013621-image.png

                        M Offline
                        M Offline
                        mpergand
                        wrote on last edited by mpergand
                        #11

                        @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.

                        1 Reply Last reply
                        0
                        • I Offline
                          I Offline
                          imene
                          wrote on last edited by
                          #12

                          @jsulm
                          i found this code here https://doc.qt.io/qt-6/qqueue.html

                          QQueue<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);
                           }
                          
                          1 Reply Last reply
                          0
                          • I Offline
                            I Offline
                            imene
                            wrote on last edited by imene
                            #13

                            @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 ?

                            M 1 Reply Last reply
                            0
                            • M mpergand

                              @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.

                              I Offline
                              I Offline
                              imene
                              wrote on last edited by
                              #14

                              @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);
                                  }
                              
                                 }
                              
                              1 Reply Last reply
                              0
                              • I imene

                                @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 ?

                                M Offline
                                M Offline
                                mpergand
                                wrote on last edited by mpergand
                                #15

                                @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.

                                I 1 Reply Last reply
                                0
                                • M mpergand

                                  @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.

                                  I Offline
                                  I Offline
                                  imene
                                  wrote on last edited by imene
                                  #16

                                  @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;
                                  
                                  1 Reply Last reply
                                  0
                                  • M Offline
                                    M Offline
                                    mpergand
                                    wrote on last edited by
                                    #17

                                    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();
                                    
                                    1 Reply Last reply
                                    0
                                    • I Offline
                                      I Offline
                                      imene
                                      wrote on last edited by imene
                                      #18

                                      I want to put this function inside connect but it don't work;
                                      void MainWindow::sendFrame(int i)

                                       connect(m_speedTimer,&QTimer::timeout, this, &MainWindow::sendFrame);
                                      

                                      984e6894-0e6d-4d50-9251-cb8e869d2150-image.png

                                      jsulmJ 1 Reply Last reply
                                      0
                                      • I imene

                                        I want to put this function inside connect but it don't work;
                                        void MainWindow::sendFrame(int i)

                                         connect(m_speedTimer,&QTimer::timeout, this, &MainWindow::sendFrame);
                                        

                                        984e6894-0e6d-4d50-9251-cb8e869d2150-image.png

                                        jsulmJ Offline
                                        jsulmJ Offline
                                        jsulm
                                        Lifetime Qt Champion
                                        wrote on last edited by
                                        #19

                                        @imene The error is clear, isn't it?
                                        The arguments of the signal and slot do not match. You can use a lambda as slot to work around this.

                                        https://forum.qt.io/topic/113070/qt-code-of-conduct

                                        1 Reply Last reply
                                        1
                                        • I Offline
                                          I Offline
                                          imene
                                          wrote on last edited by
                                          #20

                                          This is my sendFrame function how can i pass it as a slot with its parameter that changes each timeout ?

                                          class MainWindow : public QMainWindow
                                          {
                                          ....
                                          private slots:
                                           void sendFrame(QString IdData_R,QString PayloadData_R,int i);
                                          }
                                          
                                          jsulmJ 1 Reply Last reply
                                          0

                                          • Login

                                          • Login or register to search.
                                          • First post
                                            Last post
                                          0
                                          • Categories
                                          • Recent
                                          • Tags
                                          • Popular
                                          • Users
                                          • Groups
                                          • Search
                                          • Get Qt Extensions
                                          • Unsolved