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