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 to create some Timers at run time and handle them?
Forum Updated to NodeBB v4.3 + New Features

How to create some Timers at run time and handle them?

Scheduled Pinned Locked Moved Solved General and Desktop
qtimer
19 Posts 6 Posters 3.7k 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.
  • mrjjM mrjj

    Hi
    What about using lambdas and capture the timer?
    Then you don't need to keep track of anything.

    QObject::connect(timer, &QTimer::timeout, [timer](){
    
        timer->stop();
    
    });
    
    QObject::connect(timerOther, &QTimer::timeout, [timerOther](){
    
        timerOther->stop();
    
    });
    
    
    
    JamshidJ Offline
    JamshidJ Offline
    Jamshid
    wrote on last edited by Jamshid
    #6

    @mrjj I don't know how many timers should I need in program, they are created with respect to input data.

    1 Reply Last reply
    0
    • Christian EhrlicherC Online
      Christian EhrlicherC Online
      Christian Ehrlicher
      Lifetime Qt Champion
      wrote on last edited by
      #7

      @Jamshid said in How to create some Timers at run time and handle them?:

      So using QTimer with specific slots won't work.

      There is always QObject::sender() where you can see where the signal is coming from. Apart from this why not storing all created timers in a QVector/QHash/whatever so you can access them later on?

      Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
      Visit the Qt Academy at https://academy.qt.io/catalog

      JamshidJ 1 Reply Last reply
      2
      • artwawA artwaw

        @Jamshid Unless someone more experienced have other way I'd go somewhere along that way:

        • derive from QTimer and include just one field: id, lets assume it is qint32 or something and name teh class here QTimer2;
        • create QHash<int,QTimer2*>

        And store the pointers and position that is equal to field id in QTimer2. This way you'll be able to examine which instance called and connect signals/slots.

        Mind you, I don't find this solution very elegant. This is only rough idea and there might be better one.

        JamshidJ Offline
        JamshidJ Offline
        Jamshid
        wrote on last edited by
        #8

        @artwaw I'm new to Qt but I'll try it. Thanks.

        1 Reply Last reply
        1
        • Christian EhrlicherC Christian Ehrlicher

          @Jamshid said in How to create some Timers at run time and handle them?:

          So using QTimer with specific slots won't work.

          There is always QObject::sender() where you can see where the signal is coming from. Apart from this why not storing all created timers in a QVector/QHash/whatever so you can access them later on?

          JamshidJ Offline
          JamshidJ Offline
          Jamshid
          wrote on last edited by
          #9

          @Christian-Ehrlicher I'm trying sender(), I can store created timers in a vector and connect all created timers' timeout signal to one slot, my problem is this how to determine in that slot which timer timed out. I think QObject::sender() will help. let me try it.

          J.HilkJ JonBJ 2 Replies Last reply
          0
          • JamshidJ Jamshid

            @Christian-Ehrlicher I'm trying sender(), I can store created timers in a vector and connect all created timers' timeout signal to one slot, my problem is this how to determine in that slot which timer timed out. I think QObject::sender() will help. let me try it.

            J.HilkJ Offline
            J.HilkJ Offline
            J.Hilk
            Moderators
            wrote on last edited by J.Hilk
            #10

            @Jamshid I would actually suggest to use a lambda over the sender() approach

            for(int i(0); i <10; i++){
                    QTimer *t = new QTimer(this);
                    connect(t, &QTimer::timeout, this, [=]()->void{timerSlot(i);});
                    m_timers.append(t);
               }
            
            ...
            public slots:
                void timerSlot(int timeId);
            

            Be aware of the Qt Code of Conduct, when posting : https://forum.qt.io/topic/113070/qt-code-of-conduct


            Q: What's that?
            A: It's blue light.
            Q: What does it do?
            A: It turns blue.

            JamshidJ 1 Reply Last reply
            0
            • JamshidJ Jamshid

              @Christian-Ehrlicher I'm trying sender(), I can store created timers in a vector and connect all created timers' timeout signal to one slot, my problem is this how to determine in that slot which timer timed out. I think QObject::sender() will help. let me try it.

              JonBJ Online
              JonBJ Online
              JonB
              wrote on last edited by
              #11

              @Jamshid
              For a slot function sender should give you which timer. My understanding (untested!) is that if you use a lambda you do not get a sender. But then @J-Hilk is, I think, offering a lambda which passes the timerId as a parameter for you. Both sound like they would work.

              J.HilkJ 1 Reply Last reply
              0
              • JonBJ JonB

                @Jamshid
                For a slot function sender should give you which timer. My understanding (untested!) is that if you use a lambda you do not get a sender. But then @J-Hilk is, I think, offering a lambda which passes the timerId as a parameter for you. Both sound like they would work.

                J.HilkJ Offline
                J.HilkJ Offline
                J.Hilk
                Moderators
                wrote on last edited by
                #12

                @JonB well, yes, we originally talked about identifying the timer that called the slot, what better way than an int ? 😉

                Well, If one is more interested in the Timer Object....

                for(int i(0); i <10; i++){
                        QTimer *t = new QTimer(this);
                        connect(t, &QTimer::timeout, this, [=]()->void{timerSlot(t);});
                        m_timers.append(t);
                   }
                
                ...
                public slots:
                    void timerSlot(QTimer *timer);
                

                Be aware of the Qt Code of Conduct, when posting : https://forum.qt.io/topic/113070/qt-code-of-conduct


                Q: What's that?
                A: It's blue light.
                Q: What does it do?
                A: It turns blue.

                1 Reply Last reply
                4
                • J.HilkJ J.Hilk

                  @Jamshid I would actually suggest to use a lambda over the sender() approach

                  for(int i(0); i <10; i++){
                          QTimer *t = new QTimer(this);
                          connect(t, &QTimer::timeout, this, [=]()->void{timerSlot(i);});
                          m_timers.append(t);
                     }
                  
                  ...
                  public slots:
                      void timerSlot(int timeId);
                  
                  JamshidJ Offline
                  JamshidJ Offline
                  Jamshid
                  wrote on last edited by Jamshid
                  #13

                  @J-Hilk I test this code, It only passes the last timer ID.

                  if (!List.contains(str))
                  {
                  // Start timer
                  timer = new QTimer(this);
                  timer->setInterval(200);
                  timer->start();
                  connect(timer, &QTimer::timeout, this, [=]()->void{integrityTimersEvent(timer->timerId());});
                  
                  //
                  timersList.append(timer);
                  timersIDList.append(timer->timerId());
                  }
                  

                  void FrameProcessor::integrityTimersEvent(int timerID)
                  {
                      qDebug() << "integrityTimersEvent => Timer ID:" << timerID;
                  }
                  

                  Am I doing it right way?

                  JonBJ J.HilkJ Christian EhrlicherC 4 Replies Last reply
                  0
                  • JamshidJ Jamshid

                    @J-Hilk I test this code, It only passes the last timer ID.

                    if (!List.contains(str))
                    {
                    // Start timer
                    timer = new QTimer(this);
                    timer->setInterval(200);
                    timer->start();
                    connect(timer, &QTimer::timeout, this, [=]()->void{integrityTimersEvent(timer->timerId());});
                    
                    //
                    timersList.append(timer);
                    timersIDList.append(timer->timerId());
                    }
                    

                    void FrameProcessor::integrityTimersEvent(int timerID)
                    {
                        qDebug() << "integrityTimersEvent => Timer ID:" << timerID;
                    }
                    

                    Am I doing it right way?

                    JonBJ Online
                    JonBJ Online
                    JonB
                    wrote on last edited by JonB
                    #14

                    @Jamshid , @J-Hilk

                    It only passes the last timer ID.

                    This is just the kind of behaviour I found when playing with lambdas (which is why I don't much like them, let's not go there)! To get it right, I believe, you must pass the timer->timerID(), or the whole timer, as a parameter to the lambda. Not sure of the C++ (I'm Python) syntax, but I think it must go inside the () you have...

                    EDIT Oh well, since @J-Hilk shows it works below, I must be mistaken, sorry.... I had this kind of problem with Python lambdas, they must not directly access a changing value in the caller in their body code, instead the caller must pass that as a parameter....

                    1 Reply Last reply
                    0
                    • JamshidJ Jamshid

                      @J-Hilk I test this code, It only passes the last timer ID.

                      if (!List.contains(str))
                      {
                      // Start timer
                      timer = new QTimer(this);
                      timer->setInterval(200);
                      timer->start();
                      connect(timer, &QTimer::timeout, this, [=]()->void{integrityTimersEvent(timer->timerId());});
                      
                      //
                      timersList.append(timer);
                      timersIDList.append(timer->timerId());
                      }
                      

                      void FrameProcessor::integrityTimersEvent(int timerID)
                      {
                          qDebug() << "integrityTimersEvent => Timer ID:" << timerID;
                      }
                      

                      Am I doing it right way?

                      J.HilkJ Offline
                      J.HilkJ Offline
                      J.Hilk
                      Moderators
                      wrote on last edited by J.Hilk
                      #15

                      @Jamshid
                      should work fine,

                      take a look at the example I made:

                      int MainWindow::count = 0;
                      MainWindow::MainWindow(QWidget *parent) :
                          QMainWindow(parent),
                          ui(new Ui::MainWindow)
                      {
                          for(int i(0); i <10; i++){
                              QTimer *t = new QTimer(this);
                              connect(t, &QTimer::timeout, this, [=]()->void{timerSlot(t->timerId());});
                              m_timers.append(t);
                              t->start(100);
                         }
                      }
                      
                      void MainWindow::timerSlot(int timerId)
                      {
                          qDebug() << timerId;
                          qDebug() << Q_FUNC_INFO << count++;
                      }
                      

                      which results in the correct call of:

                      1
                      void MainWindow::timerSlot(int) 0
                      2
                      void MainWindow::timerSlot(int) 1
                      3
                      void MainWindow::timerSlot(int) 2
                      4
                      void MainWindow::timerSlot(int) 3
                      5
                      void MainWindow::timerSlot(int) 4
                      6
                      void MainWindow::timerSlot(int) 5
                      7
                      void MainWindow::timerSlot(int) 6
                      8
                      void MainWindow::timerSlot(int) 7
                      9
                      void MainWindow::timerSlot(int) 8
                      10
                      void MainWindow::timerSlot(int) 9
                      1
                      void MainWindow::timerSlot(int) 10
                      2
                      void MainWindow::timerSlot(int) 11
                      3
                      void MainWindow::timerSlot(int) 12
                      4
                      void MainWindow::timerSlot(int) 13
                      5
                      void MainWindow::timerSlot(int) 14
                      6
                      void MainWindow::timerSlot(int) 15
                      7
                      void MainWindow::timerSlot(int) 16
                      8
                      void MainWindow::timerSlot(int) 17
                      9
                      void MainWindow::timerSlot(int) 18
                      10
                      void MainWindow::timerSlot(int) 19
                      1
                      void MainWindow::timerSlot(int) 20
                      2
                      void MainWindow::timerSlot(int) 21
                      3
                      void MainWindow::timerSlot(int) 22
                      4
                      void MainWindow::timerSlot(int) 23
                      5
                      void MainWindow::timerSlot(int) 24
                      6
                      void MainWindow::timerSlot(int) 25
                      7
                      void MainWindow::timerSlot(int) 26
                      8
                      void MainWindow::timerSlot(int) 27
                      9
                      void MainWindow::timerSlot(int) 28
                      10
                      void MainWindow::timerSlot(int) 29
                      1
                      void MainWindow::timerSlot(int) 30
                      2
                      void MainWindow::timerSlot(int) 31
                      3
                      void MainWindow::timerSlot(int) 32
                      4
                      void MainWindow::timerSlot(int) 33
                      5
                      void MainWindow::timerSlot(int) 34
                      6
                      void MainWindow::timerSlot(int) 35
                      7
                      void MainWindow::timerSlot(int) 36
                      8
                      void MainWindow::timerSlot(int) 37
                      9
                      void MainWindow::timerSlot(int) 38
                      10
                      void MainWindow::timerSlot(int) 39
                      1
                      void MainWindow::timerSlot(int) 40
                      2
                      void MainWindow::timerSlot(int) 41
                      3
                      void MainWindow::timerSlot(int) 42
                      4
                      void MainWindow::timerSlot(int) 43
                      5
                      void MainWindow::timerSlot(int) 44
                      6
                      void MainWindow::timerSlot(int) 45
                      7
                      void MainWindow::timerSlot(int) 46
                      8
                      void MainWindow::timerSlot(int) 47
                      9
                      void MainWindow::timerSlot(int) 48
                      10
                      void MainWindow::timerSlot(int) 49
                      1
                      void MainWindow::timerSlot(int) 50
                      

                      edit: @JonB
                      the [=] is a "capture everything by copy" indicator. So no explicit capture of the id should be required


                      Be aware of the Qt Code of Conduct, when posting : https://forum.qt.io/topic/113070/qt-code-of-conduct


                      Q: What's that?
                      A: It's blue light.
                      Q: What does it do?
                      A: It turns blue.

                      1 Reply Last reply
                      2
                      • JamshidJ Jamshid

                        @J-Hilk I test this code, It only passes the last timer ID.

                        if (!List.contains(str))
                        {
                        // Start timer
                        timer = new QTimer(this);
                        timer->setInterval(200);
                        timer->start();
                        connect(timer, &QTimer::timeout, this, [=]()->void{integrityTimersEvent(timer->timerId());});
                        
                        //
                        timersList.append(timer);
                        timersIDList.append(timer->timerId());
                        }
                        

                        void FrameProcessor::integrityTimersEvent(int timerID)
                        {
                            qDebug() << "integrityTimersEvent => Timer ID:" << timerID;
                        }
                        

                        Am I doing it right way?

                        Christian EhrlicherC Online
                        Christian EhrlicherC Online
                        Christian Ehrlicher
                        Lifetime Qt Champion
                        wrote on last edited by
                        #16

                        @Jamshid said in How to create some Timers at run time and handle them?:

                        Am I doing it right way?

                        I would guess timer is a member variable, then yes you're doing it wrong. You copy the whole context ( [=]) and therefore the access inside the lambda is 'this->timer'

                        Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
                        Visit the Qt Academy at https://academy.qt.io/catalog

                        1 Reply Last reply
                        3
                        • JamshidJ Jamshid

                          @J-Hilk I test this code, It only passes the last timer ID.

                          if (!List.contains(str))
                          {
                          // Start timer
                          timer = new QTimer(this);
                          timer->setInterval(200);
                          timer->start();
                          connect(timer, &QTimer::timeout, this, [=]()->void{integrityTimersEvent(timer->timerId());});
                          
                          //
                          timersList.append(timer);
                          timersIDList.append(timer->timerId());
                          }
                          

                          void FrameProcessor::integrityTimersEvent(int timerID)
                          {
                              qDebug() << "integrityTimersEvent => Timer ID:" << timerID;
                          }
                          

                          Am I doing it right way?

                          J.HilkJ Offline
                          J.HilkJ Offline
                          J.Hilk
                          Moderators
                          wrote on last edited by
                          #17

                          @Jamshid
                          actually this

                          timer = new QTimer(this);
                          timer->setInterval(200);
                          timer->start();
                          connect(timer, &QTimer::timeout, this, [=]()->void{integrityTimersEvent(timer->timerId());});
                          

                          is referencing the member variable

                          try the following:

                          QTimer *t = new QTimer(this);
                          t->setInterval(200);
                          t->start();
                          connect(t, &QTimer::timeout, this, [=]()->void{integrityTimersEvent(t->timerId());});
                          timer = t;
                          

                          Be aware of the Qt Code of Conduct, when posting : https://forum.qt.io/topic/113070/qt-code-of-conduct


                          Q: What's that?
                          A: It's blue light.
                          Q: What does it do?
                          A: It turns blue.

                          JamshidJ 1 Reply Last reply
                          6
                          • J.HilkJ J.Hilk

                            @Jamshid
                            actually this

                            timer = new QTimer(this);
                            timer->setInterval(200);
                            timer->start();
                            connect(timer, &QTimer::timeout, this, [=]()->void{integrityTimersEvent(timer->timerId());});
                            

                            is referencing the member variable

                            try the following:

                            QTimer *t = new QTimer(this);
                            t->setInterval(200);
                            t->start();
                            connect(t, &QTimer::timeout, this, [=]()->void{integrityTimersEvent(t->timerId());});
                            timer = t;
                            
                            JamshidJ Offline
                            JamshidJ Offline
                            Jamshid
                            wrote on last edited by
                            #18

                            @J-Hilk Thanks a lot, now it works, I'm new to Qt and this topic I think was a little bit advanced for me :)

                            1 Reply Last reply
                            2
                            • JamshidJ Offline
                              JamshidJ Offline
                              Jamshid
                              wrote on last edited by Jamshid
                              #19

                              Thank you all dear friends, that’s really kind of you.
                              Your help is so appreciated.

                              1 Reply Last reply
                              2

                              • Login

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