Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. QTimer inside a for loop
Qt 6.12 LTS is out! See what's new in the release blog

QTimer inside a for loop

Scheduled Pinned Locked Moved Unsolved General and Desktop
13 Posts 4 Posters 4.1k Views 3 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.
  • N n_moosavi

    @JonB Thanks for your reply.
    Actually i want a timer that for example after 1000s sends 1, then after 2000s from when the first one was started, sends2.
    so the timestate is [1000, 2000,3000,4000] and the packet is [1 2 3 4].

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

    @n_moosavi
    So you can implement in one of two ways, as you choose:

    • Create 4 separate QTimer (singleshot) instances, all connected to same senddata() slot, each one with each of the timeout durations in your timestate array.

    • Create one QTimer (singleshot). Keep a member variable to count through timestate so you know where you have got to. On the timeout, apart from doing the sendata(), advance the counter, if it's not at end calculate the difference between the value in timestate for this time's value and the previous one, re-load the single QTimer instance with that (all would be 1000 given the values you presently show in timestate).

    N 1 Reply Last reply
    2
    • JonBJ JonB

      @n_moosavi
      So you can implement in one of two ways, as you choose:

      • Create 4 separate QTimer (singleshot) instances, all connected to same senddata() slot, each one with each of the timeout durations in your timestate array.

      • Create one QTimer (singleshot). Keep a member variable to count through timestate so you know where you have got to. On the timeout, apart from doing the sendata(), advance the counter, if it's not at end calculate the difference between the value in timestate for this time's value and the previous one, re-load the single QTimer instance with that (all would be 1000 given the values you presently show in timestate).

      N Offline
      N Offline
      n_moosavi
      wrote on last edited by n_moosavi
      #5

      @JonB For the first way. I tried as follows. I have created 3 separate QTimer:{timer,timerr,timerrr}
      .But still, only the last timer works and sends data.

              timer = new QTimer(this);
              send=1;
              connect(timer, SIGNAL(timeout()), this, SLOT(senddata()));
              timer->setSingleShot(true);
              timer->start(timestate[0]);
      
              timerr = new QTimer(this);
              send=2;
              connect(timerr, SIGNAL(timeout()), this, SLOT(senddata()));
              timerr->setSingleShot(true);
              timerr->start(timestate[1]);
      
              timerrr = new QTimer(this);
              send=3;
              connect(timerrr, SIGNAL(timeout()), this, SLOT(senddata()));
              timerrr->setSingleShot(true);
              timerrr->start(timestate[2]);
      
      JonBJ M 2 Replies Last reply
      0
      • N n_moosavi

        @JonB For the first way. I tried as follows. I have created 3 separate QTimer:{timer,timerr,timerrr}
        .But still, only the last timer works and sends data.

                timer = new QTimer(this);
                send=1;
                connect(timer, SIGNAL(timeout()), this, SLOT(senddata()));
                timer->setSingleShot(true);
                timer->start(timestate[0]);
        
                timerr = new QTimer(this);
                send=2;
                connect(timerr, SIGNAL(timeout()), this, SLOT(senddata()));
                timerr->setSingleShot(true);
                timerr->start(timestate[1]);
        
                timerrr = new QTimer(this);
                send=3;
                connect(timerrr, SIGNAL(timeout()), this, SLOT(senddata()));
                timerrr->setSingleShot(true);
                timerrr->start(timestate[2]);
        
        JonBJ Offline
        JonBJ Offline
        JonB
        wrote on last edited by
        #6

        @n_moosavi
        These should work. Put qDebug() << "senddata()"; as the first statement in senddata() and see how many times it outputs.

        N 1 Reply Last reply
        0
        • N n_moosavi

          @JonB For the first way. I tried as follows. I have created 3 separate QTimer:{timer,timerr,timerrr}
          .But still, only the last timer works and sends data.

                  timer = new QTimer(this);
                  send=1;
                  connect(timer, SIGNAL(timeout()), this, SLOT(senddata()));
                  timer->setSingleShot(true);
                  timer->start(timestate[0]);
          
                  timerr = new QTimer(this);
                  send=2;
                  connect(timerr, SIGNAL(timeout()), this, SLOT(senddata()));
                  timerr->setSingleShot(true);
                  timerr->start(timestate[1]);
          
                  timerrr = new QTimer(this);
                  send=3;
                  connect(timerrr, SIGNAL(timeout()), this, SLOT(senddata()));
                  timerrr->setSingleShot(true);
                  timerrr->start(timestate[2]);
          
          M Offline
          M Offline
          mpergand
          wrote on last edited by mpergand
          #7

          @n_moosavi

          QTimer as a counter using dynamic property:

          MainWindow::MainWindow(QWidget *parent)
              : QMainWindow(parent)
          {
              auto* timer=new QTimer;
              timer->setProperty("count",5);
              connect(timer,&QTimer::timeout,this, &MainWindow::timeout);
              timer->start(1000);
          }
          
          void MainWindow::timeout()
          {
              QTimer* timer=qobject_cast<QTimer*>(sender());
              if(timer==nullptr) return; // error wrong sender
          
              int count=timer->property("count").toInt()-1;
              timer->setProperty("count",count);
          
              qDebug()<<__FUNCTION__<<count;
              
              // call sendData() here
          
              if(count<=0)
                  {
                  timer->stop();
                  delete timer;
                  }
          }
          
          
          N 1 Reply Last reply
          0
          • JonBJ JonB

            @n_moosavi
            These should work. Put qDebug() << "senddata()"; as the first statement in senddata() and see how many times it outputs.

            N Offline
            N Offline
            n_moosavi
            wrote on last edited by n_moosavi
            #8

            @JonB Dear JohB.
            I added the qDebug() << "senddata()"; to the senddata. Then i run
            It outputs 3 times and each time with the last packet. It sends the last packet 3 times.
            I tested it with switch/case but it still sends the last packet .
            for (int i = 0; i < 4; i++)
            {
            switch(timestate[i]) {
            case 1000:
            send[2]=LightState(0);
            connect(timer, SIGNAL(timeout()), this, SLOT(senddata()));
            timer->setSingleShot(true);
            timer->start(timestate[0]);
            case 2000:
            send[2]=LightState(1);
            connect(timerr, SIGNAL(timeout()), this, SLOT(senddata()));
            timerr->setSingleShot(true);
            timerr->start(timestate[1]);
            case 3000:
            send[2]=LightState(2);
            connect(timerrr, SIGNAL(timeout()), this, SLOT(senddata()));
            timerrr->setSingleShot(true);
            timerrr->start(timestate[2]);
            }
            }

            JonBJ 1 Reply Last reply
            0
            • Kent-DorfmanK Offline
              Kent-DorfmanK Offline
              Kent-Dorfman
              wrote on last edited by
              #9

              there really needs to be a "required reading" section for Qt, before people ask questions. As we see again, trying to use sequential/procedural programming instead of the event driven model.

              staggering timer events only needs a single timer implementation. in the callback from Qtimer(1000ms)::TimerExpired() execute a switch sstatement based on a static var that is incremented every time the timer expires. in the "case" segments put your light (on/off) logic.

              The dystopian literature that served as a warning in my youth has become an instruction manual in my elder years.

              N 1 Reply Last reply
              1
              • N n_moosavi

                @JonB Dear JohB.
                I added the qDebug() << "senddata()"; to the senddata. Then i run
                It outputs 3 times and each time with the last packet. It sends the last packet 3 times.
                I tested it with switch/case but it still sends the last packet .
                for (int i = 0; i < 4; i++)
                {
                switch(timestate[i]) {
                case 1000:
                send[2]=LightState(0);
                connect(timer, SIGNAL(timeout()), this, SLOT(senddata()));
                timer->setSingleShot(true);
                timer->start(timestate[0]);
                case 2000:
                send[2]=LightState(1);
                connect(timerr, SIGNAL(timeout()), this, SLOT(senddata()));
                timerr->setSingleShot(true);
                timerr->start(timestate[1]);
                case 3000:
                send[2]=LightState(2);
                connect(timerrr, SIGNAL(timeout()), this, SLOT(senddata()));
                timerrr->setSingleShot(true);
                timerrr->start(timestate[2]);
                }
                }

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

                @n_moosavi
                So you know your senddata() slot is being hit 3 times, which was the objective of the exercise. What you do in senddata() is up to you, you seem to write(send);. And that will be in whatever state you left it after your for ... switch loop, which perhaps means send[2]=LightState(2);, and that is what you are complaining about.

                Since the loop runs when you are setting the timers up, not when the timers expire, if you change send[] there that will affect when all the timers expire, which is perhaps not what you want. So you need to alter code in that light.

                N 1 Reply Last reply
                0
                • Kent-DorfmanK Kent-Dorfman

                  there really needs to be a "required reading" section for Qt, before people ask questions. As we see again, trying to use sequential/procedural programming instead of the event driven model.

                  staggering timer events only needs a single timer implementation. in the callback from Qtimer(1000ms)::TimerExpired() execute a switch sstatement based on a static var that is incremented every time the timer expires. in the "case" segments put your light (on/off) logic.

                  N Offline
                  N Offline
                  n_moosavi
                  wrote on last edited by n_moosavi
                  #11

                  @Kent-Dorfman thanks for your help, I'm new to QT, and I know that I should work harder.

                  1 Reply Last reply
                  0
                  • M mpergand

                    @n_moosavi

                    QTimer as a counter using dynamic property:

                    MainWindow::MainWindow(QWidget *parent)
                        : QMainWindow(parent)
                    {
                        auto* timer=new QTimer;
                        timer->setProperty("count",5);
                        connect(timer,&QTimer::timeout,this, &MainWindow::timeout);
                        timer->start(1000);
                    }
                    
                    void MainWindow::timeout()
                    {
                        QTimer* timer=qobject_cast<QTimer*>(sender());
                        if(timer==nullptr) return; // error wrong sender
                    
                        int count=timer->property("count").toInt()-1;
                        timer->setProperty("count",count);
                    
                        qDebug()<<__FUNCTION__<<count;
                        
                        // call sendData() here
                    
                        if(count<=0)
                            {
                            timer->stop();
                            delete timer;
                            }
                    }
                    
                    
                    N Offline
                    N Offline
                    n_moosavi
                    wrote on last edited by
                    #12

                    @mpergand thanks for your help

                    1 Reply Last reply
                    0
                    • JonBJ JonB

                      @n_moosavi
                      So you know your senddata() slot is being hit 3 times, which was the objective of the exercise. What you do in senddata() is up to you, you seem to write(send);. And that will be in whatever state you left it after your for ... switch loop, which perhaps means send[2]=LightState(2);, and that is what you are complaining about.

                      Since the loop runs when you are setting the timers up, not when the timers expire, if you change send[] there that will affect when all the timers expire, which is perhaps not what you want. So you need to alter code in that light.

                      N Offline
                      N Offline
                      n_moosavi
                      wrote on last edited by
                      #13

                      @JonB thanks for your help

                      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
                      • Unsolved