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.9k 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.
  • JamshidJ Jamshid

    @artwaw thanks,
    startTimer() does not have reset function and when I create some timers with this method can't have access to them later for restarting. They just provide their ID and I did timerEvent() override.
    In my application It's not determined how many timers needed, maybe 2 or maybe 100.
    So using QTimer with specific slots won't work.

    artwawA Offline
    artwawA Offline
    artwaw
    wrote on last edited by artwaw
    #5

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

    For more information please re-read.

    Kind Regards,
    Artur

    JamshidJ 1 Reply Last reply
    0
    • 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 Offline
        Christian EhrlicherC Offline
        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 Offline
                JonBJ Offline
                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 Offline
                      JonBJ Offline
                      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 Offline
                          Christian EhrlicherC Offline
                          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