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 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
                                      • I imene

                                        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 Offline
                                        jsulmJ Offline
                                        jsulm
                                        Lifetime Qt Champion
                                        wrote on last edited by
                                        #21

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

                                        how can i pass it as a slot with its parameter that changes each timeout

                                        I already told you how: "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

                                        • Login

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