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. The timeout slot is not fired when the timer is called from a separate thread in the main()
Forum Update on Monday, May 27th 2025

The timeout slot is not fired when the timer is called from a separate thread in the main()

Scheduled Pinned Locked Moved Solved General and Desktop
7 Posts 4 Posters 401 Views
  • 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.
  • S Offline
    S Offline
    Stavros Vaionitis
    wrote on last edited by
    #1

    Hi there,

    I have the following code

    #include <QtConcurrent/QtConcurrent>
    #include <QApplication>
    #include <QDateTime>
    #include <QDebug>
    #include <QObject>
    #include <QTimer>
    
    class PrintThreadIdTimer : public QObject
    {
        Q_OBJECT
    public:
        PrintThreadIdTimer(int interval, QObject *parent = nullptr)
        {
            m_timer = new QTimer(this);
            m_timer->setInterval(interval);
            connect(m_timer, &QTimer::timeout, this, &PrintThreadIdTimer::printThreadIdAndTimeMsecs);
        }
    
        ~PrintThreadIdTimer()
        {
            disconnect(m_timer, &QTimer::timeout, this, &PrintThreadIdTimer::printThreadIdAndTimeMsecs);
    
            delete m_timer;
            m_timer = nullptr;
        }
    
        void start()
        {
            m_timer->start();
        }
    
        void stop()
        {
            m_timer->stop();
        }
    
        int interval()
        {
            return m_timer->interval();
        }
    
    public slots:
        void printThreadIdAndTimeMsecs()
        {
            qDebug() << Q_FUNC_INFO << "ThreadId:" << QThread::currentThreadId()
                     << "TimeMsecs:" << QDateTime::currentMSecsSinceEpoch();
        }
    
    private:
        QTimer *m_timer = nullptr;
    };
    
    int main(int argc, char *argv[])
    {
        QApplication app(argc, argv);
    
        qDebug() << Q_FUNC_INFO << "Thread:" << QThread::currentThreadId()
                 << "Time:" << QDateTime::currentMSecsSinceEpoch();
    
        auto appRunAndExit = [=]()
        {
            // Just wait a little bit to enter the event loop
            QThread::msleep(1000);
    
            PrintThreadIdTimer *printThreadTimer = new PrintThreadIdTimer(1000);
    
            printThreadTimer->start();
    
            for (int i = 0; i < 3; ++i)
            {
                qDebug() << Q_FUNC_INFO
                         << "ThreadId:" << QThread::currentThreadId()
                         << "interval():" << printThreadTimer->interval()
                         << "Time:" << QDateTime::currentMSecsSinceEpoch();
    
                QThread::msleep(1000);
            }
    
            printThreadTimer->stop();
    
            QCoreApplication::quit();
        };
        QThreadPool::globalInstance()->start(appRunAndExit);
    
        qDebug() << Q_FUNC_INFO << "-> Thread:" << QThread::currentThreadId()
                 << "Time:" << QDateTime::currentMSecsSinceEpoch();
    
        int out = app.exec();
    
        qDebug() << Q_FUNC_INFO << "---> Thread:" << QThread::currentThreadId()
                 << "Time:" << QDateTime::currentMSecsSinceEpoch();
    
        return out;
    }
    
    #include "cpp-qt6-threaded-timers.moc"
    

    The class PrintThreadIdTimer is just a wrapper class on a QTimer which is calling the printThreadIdAndTimeMsecs when the timeout signal is sent.

    Now I wanted to use this class on a simple application, but as far as I know, the QTimer needs an event loop, so I used the QApplication::exec().

    I used the lambda function appRunAndExit () in order to create a simple example where I am using the PrintThreadIdTimer and then closing the application. I run this function on a separate thread using QThreadPool::globalInstance()->start().

    Now, when I run the above example, it seems that the slot function is not called, and I am not really sure why. The output that I am getting is the following

    int main(int, char**) Thread: 0x7f420c7ca880 Time: 1700741341051
    int main(int, char**) -> Thread: 0x7f420c7ca880 Time: 1700741341052
    main(int, char**)::<lambda()> ThreadId: 0x7f4201f7a640 interval(): 1000 Time: 1700741342052
    main(int, char**)::<lambda()> ThreadId: 0x7f4201f7a640 interval(): 1000 Time: 1700741343053
    main(int, char**)::<lambda()> ThreadId: 0x7f4201f7a640 interval(): 1000 Time: 1700741344054
    int main(int, char**) ---> Thread: 0x7f420c7ca880 Time: 1700741345055
    

    What is the issue in the above code? Do I need to change something, or have I understood something wrong?

    I am using Qt 6.2.5.

    Let me know if you need more information.

    Kind regards,

    Stavros

    jsulmJ JonBJ 2 Replies Last reply
    0
    • S Stavros Vaionitis

      Hi there,

      I have the following code

      #include <QtConcurrent/QtConcurrent>
      #include <QApplication>
      #include <QDateTime>
      #include <QDebug>
      #include <QObject>
      #include <QTimer>
      
      class PrintThreadIdTimer : public QObject
      {
          Q_OBJECT
      public:
          PrintThreadIdTimer(int interval, QObject *parent = nullptr)
          {
              m_timer = new QTimer(this);
              m_timer->setInterval(interval);
              connect(m_timer, &QTimer::timeout, this, &PrintThreadIdTimer::printThreadIdAndTimeMsecs);
          }
      
          ~PrintThreadIdTimer()
          {
              disconnect(m_timer, &QTimer::timeout, this, &PrintThreadIdTimer::printThreadIdAndTimeMsecs);
      
              delete m_timer;
              m_timer = nullptr;
          }
      
          void start()
          {
              m_timer->start();
          }
      
          void stop()
          {
              m_timer->stop();
          }
      
          int interval()
          {
              return m_timer->interval();
          }
      
      public slots:
          void printThreadIdAndTimeMsecs()
          {
              qDebug() << Q_FUNC_INFO << "ThreadId:" << QThread::currentThreadId()
                       << "TimeMsecs:" << QDateTime::currentMSecsSinceEpoch();
          }
      
      private:
          QTimer *m_timer = nullptr;
      };
      
      int main(int argc, char *argv[])
      {
          QApplication app(argc, argv);
      
          qDebug() << Q_FUNC_INFO << "Thread:" << QThread::currentThreadId()
                   << "Time:" << QDateTime::currentMSecsSinceEpoch();
      
          auto appRunAndExit = [=]()
          {
              // Just wait a little bit to enter the event loop
              QThread::msleep(1000);
      
              PrintThreadIdTimer *printThreadTimer = new PrintThreadIdTimer(1000);
      
              printThreadTimer->start();
      
              for (int i = 0; i < 3; ++i)
              {
                  qDebug() << Q_FUNC_INFO
                           << "ThreadId:" << QThread::currentThreadId()
                           << "interval():" << printThreadTimer->interval()
                           << "Time:" << QDateTime::currentMSecsSinceEpoch();
      
                  QThread::msleep(1000);
              }
      
              printThreadTimer->stop();
      
              QCoreApplication::quit();
          };
          QThreadPool::globalInstance()->start(appRunAndExit);
      
          qDebug() << Q_FUNC_INFO << "-> Thread:" << QThread::currentThreadId()
                   << "Time:" << QDateTime::currentMSecsSinceEpoch();
      
          int out = app.exec();
      
          qDebug() << Q_FUNC_INFO << "---> Thread:" << QThread::currentThreadId()
                   << "Time:" << QDateTime::currentMSecsSinceEpoch();
      
          return out;
      }
      
      #include "cpp-qt6-threaded-timers.moc"
      

      The class PrintThreadIdTimer is just a wrapper class on a QTimer which is calling the printThreadIdAndTimeMsecs when the timeout signal is sent.

      Now I wanted to use this class on a simple application, but as far as I know, the QTimer needs an event loop, so I used the QApplication::exec().

      I used the lambda function appRunAndExit () in order to create a simple example where I am using the PrintThreadIdTimer and then closing the application. I run this function on a separate thread using QThreadPool::globalInstance()->start().

      Now, when I run the above example, it seems that the slot function is not called, and I am not really sure why. The output that I am getting is the following

      int main(int, char**) Thread: 0x7f420c7ca880 Time: 1700741341051
      int main(int, char**) -> Thread: 0x7f420c7ca880 Time: 1700741341052
      main(int, char**)::<lambda()> ThreadId: 0x7f4201f7a640 interval(): 1000 Time: 1700741342052
      main(int, char**)::<lambda()> ThreadId: 0x7f4201f7a640 interval(): 1000 Time: 1700741343053
      main(int, char**)::<lambda()> ThreadId: 0x7f4201f7a640 interval(): 1000 Time: 1700741344054
      int main(int, char**) ---> Thread: 0x7f420c7ca880 Time: 1700741345055
      

      What is the issue in the above code? Do I need to change something, or have I understood something wrong?

      I am using Qt 6.2.5.

      Let me know if you need more information.

      Kind regards,

      Stavros

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

      @Stavros-Vaionitis
      @jsulm knows better than I. It's not a good idea to do sleepy stuff, but I'm not sure that would be the issue here if the timer never runs.

      Your thread needs to run a Qt event loop (itself, not just the one in the main thread) for timers to work. I'm not sure your lambda runnable does this (from QRunnable::run()). QThread::run() does. Perhaps @jsulm or someone would comment on whether this is correct/the issue?

      1 Reply Last reply
      1
      • S Stavros Vaionitis

        Hi there,

        I have the following code

        #include <QtConcurrent/QtConcurrent>
        #include <QApplication>
        #include <QDateTime>
        #include <QDebug>
        #include <QObject>
        #include <QTimer>
        
        class PrintThreadIdTimer : public QObject
        {
            Q_OBJECT
        public:
            PrintThreadIdTimer(int interval, QObject *parent = nullptr)
            {
                m_timer = new QTimer(this);
                m_timer->setInterval(interval);
                connect(m_timer, &QTimer::timeout, this, &PrintThreadIdTimer::printThreadIdAndTimeMsecs);
            }
        
            ~PrintThreadIdTimer()
            {
                disconnect(m_timer, &QTimer::timeout, this, &PrintThreadIdTimer::printThreadIdAndTimeMsecs);
        
                delete m_timer;
                m_timer = nullptr;
            }
        
            void start()
            {
                m_timer->start();
            }
        
            void stop()
            {
                m_timer->stop();
            }
        
            int interval()
            {
                return m_timer->interval();
            }
        
        public slots:
            void printThreadIdAndTimeMsecs()
            {
                qDebug() << Q_FUNC_INFO << "ThreadId:" << QThread::currentThreadId()
                         << "TimeMsecs:" << QDateTime::currentMSecsSinceEpoch();
            }
        
        private:
            QTimer *m_timer = nullptr;
        };
        
        int main(int argc, char *argv[])
        {
            QApplication app(argc, argv);
        
            qDebug() << Q_FUNC_INFO << "Thread:" << QThread::currentThreadId()
                     << "Time:" << QDateTime::currentMSecsSinceEpoch();
        
            auto appRunAndExit = [=]()
            {
                // Just wait a little bit to enter the event loop
                QThread::msleep(1000);
        
                PrintThreadIdTimer *printThreadTimer = new PrintThreadIdTimer(1000);
        
                printThreadTimer->start();
        
                for (int i = 0; i < 3; ++i)
                {
                    qDebug() << Q_FUNC_INFO
                             << "ThreadId:" << QThread::currentThreadId()
                             << "interval():" << printThreadTimer->interval()
                             << "Time:" << QDateTime::currentMSecsSinceEpoch();
        
                    QThread::msleep(1000);
                }
        
                printThreadTimer->stop();
        
                QCoreApplication::quit();
            };
            QThreadPool::globalInstance()->start(appRunAndExit);
        
            qDebug() << Q_FUNC_INFO << "-> Thread:" << QThread::currentThreadId()
                     << "Time:" << QDateTime::currentMSecsSinceEpoch();
        
            int out = app.exec();
        
            qDebug() << Q_FUNC_INFO << "---> Thread:" << QThread::currentThreadId()
                     << "Time:" << QDateTime::currentMSecsSinceEpoch();
        
            return out;
        }
        
        #include "cpp-qt6-threaded-timers.moc"
        

        The class PrintThreadIdTimer is just a wrapper class on a QTimer which is calling the printThreadIdAndTimeMsecs when the timeout signal is sent.

        Now I wanted to use this class on a simple application, but as far as I know, the QTimer needs an event loop, so I used the QApplication::exec().

        I used the lambda function appRunAndExit () in order to create a simple example where I am using the PrintThreadIdTimer and then closing the application. I run this function on a separate thread using QThreadPool::globalInstance()->start().

        Now, when I run the above example, it seems that the slot function is not called, and I am not really sure why. The output that I am getting is the following

        int main(int, char**) Thread: 0x7f420c7ca880 Time: 1700741341051
        int main(int, char**) -> Thread: 0x7f420c7ca880 Time: 1700741341052
        main(int, char**)::<lambda()> ThreadId: 0x7f4201f7a640 interval(): 1000 Time: 1700741342052
        main(int, char**)::<lambda()> ThreadId: 0x7f4201f7a640 interval(): 1000 Time: 1700741343053
        main(int, char**)::<lambda()> ThreadId: 0x7f4201f7a640 interval(): 1000 Time: 1700741344054
        int main(int, char**) ---> Thread: 0x7f420c7ca880 Time: 1700741345055
        

        What is the issue in the above code? Do I need to change something, or have I understood something wrong?

        I am using Qt 6.2.5.

        Let me know if you need more information.

        Kind regards,

        Stavros

        jsulmJ Offline
        jsulmJ Offline
        jsulm
        Lifetime Qt Champion
        wrote on last edited by
        #2

        @Stavros-Vaionitis said in The timeout slot is not fired when the timer is called from a separate thread in the main():

        What is the issue in the above code?

        The for loop with QThread::msleep(1000) - don't do such things in event driven applications.

        https://forum.qt.io/topic/113070/qt-code-of-conduct

        S 1 Reply Last reply
        0
        • S Stavros Vaionitis

          Hi there,

          I have the following code

          #include <QtConcurrent/QtConcurrent>
          #include <QApplication>
          #include <QDateTime>
          #include <QDebug>
          #include <QObject>
          #include <QTimer>
          
          class PrintThreadIdTimer : public QObject
          {
              Q_OBJECT
          public:
              PrintThreadIdTimer(int interval, QObject *parent = nullptr)
              {
                  m_timer = new QTimer(this);
                  m_timer->setInterval(interval);
                  connect(m_timer, &QTimer::timeout, this, &PrintThreadIdTimer::printThreadIdAndTimeMsecs);
              }
          
              ~PrintThreadIdTimer()
              {
                  disconnect(m_timer, &QTimer::timeout, this, &PrintThreadIdTimer::printThreadIdAndTimeMsecs);
          
                  delete m_timer;
                  m_timer = nullptr;
              }
          
              void start()
              {
                  m_timer->start();
              }
          
              void stop()
              {
                  m_timer->stop();
              }
          
              int interval()
              {
                  return m_timer->interval();
              }
          
          public slots:
              void printThreadIdAndTimeMsecs()
              {
                  qDebug() << Q_FUNC_INFO << "ThreadId:" << QThread::currentThreadId()
                           << "TimeMsecs:" << QDateTime::currentMSecsSinceEpoch();
              }
          
          private:
              QTimer *m_timer = nullptr;
          };
          
          int main(int argc, char *argv[])
          {
              QApplication app(argc, argv);
          
              qDebug() << Q_FUNC_INFO << "Thread:" << QThread::currentThreadId()
                       << "Time:" << QDateTime::currentMSecsSinceEpoch();
          
              auto appRunAndExit = [=]()
              {
                  // Just wait a little bit to enter the event loop
                  QThread::msleep(1000);
          
                  PrintThreadIdTimer *printThreadTimer = new PrintThreadIdTimer(1000);
          
                  printThreadTimer->start();
          
                  for (int i = 0; i < 3; ++i)
                  {
                      qDebug() << Q_FUNC_INFO
                               << "ThreadId:" << QThread::currentThreadId()
                               << "interval():" << printThreadTimer->interval()
                               << "Time:" << QDateTime::currentMSecsSinceEpoch();
          
                      QThread::msleep(1000);
                  }
          
                  printThreadTimer->stop();
          
                  QCoreApplication::quit();
              };
              QThreadPool::globalInstance()->start(appRunAndExit);
          
              qDebug() << Q_FUNC_INFO << "-> Thread:" << QThread::currentThreadId()
                       << "Time:" << QDateTime::currentMSecsSinceEpoch();
          
              int out = app.exec();
          
              qDebug() << Q_FUNC_INFO << "---> Thread:" << QThread::currentThreadId()
                       << "Time:" << QDateTime::currentMSecsSinceEpoch();
          
              return out;
          }
          
          #include "cpp-qt6-threaded-timers.moc"
          

          The class PrintThreadIdTimer is just a wrapper class on a QTimer which is calling the printThreadIdAndTimeMsecs when the timeout signal is sent.

          Now I wanted to use this class on a simple application, but as far as I know, the QTimer needs an event loop, so I used the QApplication::exec().

          I used the lambda function appRunAndExit () in order to create a simple example where I am using the PrintThreadIdTimer and then closing the application. I run this function on a separate thread using QThreadPool::globalInstance()->start().

          Now, when I run the above example, it seems that the slot function is not called, and I am not really sure why. The output that I am getting is the following

          int main(int, char**) Thread: 0x7f420c7ca880 Time: 1700741341051
          int main(int, char**) -> Thread: 0x7f420c7ca880 Time: 1700741341052
          main(int, char**)::<lambda()> ThreadId: 0x7f4201f7a640 interval(): 1000 Time: 1700741342052
          main(int, char**)::<lambda()> ThreadId: 0x7f4201f7a640 interval(): 1000 Time: 1700741343053
          main(int, char**)::<lambda()> ThreadId: 0x7f4201f7a640 interval(): 1000 Time: 1700741344054
          int main(int, char**) ---> Thread: 0x7f420c7ca880 Time: 1700741345055
          

          What is the issue in the above code? Do I need to change something, or have I understood something wrong?

          I am using Qt 6.2.5.

          Let me know if you need more information.

          Kind regards,

          Stavros

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

          @Stavros-Vaionitis
          @jsulm knows better than I. It's not a good idea to do sleepy stuff, but I'm not sure that would be the issue here if the timer never runs.

          Your thread needs to run a Qt event loop (itself, not just the one in the main thread) for timers to work. I'm not sure your lambda runnable does this (from QRunnable::run()). QThread::run() does. Perhaps @jsulm or someone would comment on whether this is correct/the issue?

          1 Reply Last reply
          1
          • jsulmJ jsulm

            @Stavros-Vaionitis said in The timeout slot is not fired when the timer is called from a separate thread in the main():

            What is the issue in the above code?

            The for loop with QThread::msleep(1000) - don't do such things in event driven applications.

            S Offline
            S Offline
            Stavros Vaionitis
            wrote on last edited by
            #4

            Hi @jsulm,

            Thanks for your quick reply. I am aware about the sleep() and the for loop for event driven apps, but this is a quick and dirty example that I wanted to test QTimer with a simple example.

            Christian EhrlicherC 1 Reply Last reply
            0
            • S Stavros Vaionitis

              Hi @jsulm,

              Thanks for your quick reply. I am aware about the sleep() and the for loop for event driven apps, but this is a quick and dirty example that I wanted to test QTimer with a simple example.

              Christian EhrlicherC Offline
              Christian EhrlicherC Offline
              Christian Ehrlicher
              Lifetime Qt Champion
              wrote on last edited by
              #5

              How should the timer send a signal when there is no eventloop running where it can be created?

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

              S 1 Reply Last reply
              0
              • Christian EhrlicherC Christian Ehrlicher

                How should the timer send a signal when there is no eventloop running where it can be created?

                S Offline
                S Offline
                Stavros Vaionitis
                wrote on last edited by
                #6

                Hi @Christian-Ehrlicher and @JonB,

                Thank you for your quick replies and the valuable input. I thought that the main event loop is accessible from all the threads that are created there. I modified my code as follows

                #include <QtConcurrent/QtConcurrent>
                #include <QApplication>
                #include <QDateTime>
                #include <QDebug>
                #include <QMetaObject>
                #include <QObject>
                #include <QTimer>
                
                class PrintThreadIdTimer : public QObject
                {
                    Q_OBJECT
                public:
                    PrintThreadIdTimer(int interval, QObject *parent = nullptr)
                    {
                        m_timer = new QTimer(this);
                        m_timer->setInterval(interval);
                        connect(m_timer, &QTimer::timeout, this, &PrintThreadIdTimer::printThreadIdAndTimeMsecs);
                    }
                
                    ~PrintThreadIdTimer()
                    {
                        disconnect(m_timer, &QTimer::timeout, this, &PrintThreadIdTimer::printThreadIdAndTimeMsecs);
                
                        delete m_timer;
                        m_timer = nullptr;
                    }
                
                    int interval()
                    {
                        return m_timer->interval();
                    }
                
                public slots:
                    void start()
                    {
                        m_timer->start();
                    }
                
                    void stop()
                    {
                        m_timer->stop();
                    }
                
                private slots:
                    void printThreadIdAndTimeMsecs()
                    {
                        qDebug() << Q_FUNC_INFO << "ThreadId:" << QThread::currentThreadId()
                                 << "TimeMsecs:" << QDateTime::currentMSecsSinceEpoch();
                    }
                
                private:
                    QTimer *m_timer = nullptr;
                };
                
                int main(int argc, char *argv[])
                {
                    QApplication app(argc, argv);
                
                    qDebug() << Q_FUNC_INFO << "Thread:" << QThread::currentThreadId()
                             << "Time:" << QDateTime::currentMSecsSinceEpoch();
                
                    auto appRunAndExit = []()
                    {
                        PrintThreadIdTimer *printThreadTimer = new PrintThreadIdTimer(1000);
                        QThread *thread = new QThread();
                
                        printThreadTimer->moveToThread(thread);
                
                        QObject::connect(thread, &QThread::started, printThreadTimer, &PrintThreadIdTimer::start);
                        QObject::connect(thread, &QThread::finished, printThreadTimer, &PrintThreadIdTimer::stop);
                
                        thread->start();
                
                        for (int i = 0; i < 3; ++i)
                        {
                            qDebug() << Q_FUNC_INFO
                                     << "ThreadId:" << QThread::currentThreadId()
                                     << "interval():" << printThreadTimer->interval()
                                     << "Time:" << QDateTime::currentMSecsSinceEpoch();
                
                            QThread::msleep(1000);
                        }
                
                        thread->quit();
                        thread->wait();
                
                        QCoreApplication::quit();
                    };
                    QThreadPool::globalInstance()->start(appRunAndExit);
                
                    qDebug() << Q_FUNC_INFO << "-> Thread:" << QThread::currentThreadId()
                             << "Time:" << QDateTime::currentMSecsSinceEpoch();
                
                    int out = app.exec();
                
                    qDebug() << Q_FUNC_INFO << "---> Thread:" << QThread::currentThreadId()
                             << "Time:" << QDateTime::currentMSecsSinceEpoch();
                
                    return out;
                }
                

                Inside the lambda function I created another thread which I used it in order to move the PrintThreadIdTimer object there. I modified the class PrintThreadIdTimer in order to have start() and stop() slots to be connected with the started() and finished() signals of the thread.

                Now, it's working as expected. I am not sure if there is a better way to do this.

                Kind regards,

                Stavros

                Christian EhrlicherC 1 Reply Last reply
                0
                • S Stavros Vaionitis

                  Hi @Christian-Ehrlicher and @JonB,

                  Thank you for your quick replies and the valuable input. I thought that the main event loop is accessible from all the threads that are created there. I modified my code as follows

                  #include <QtConcurrent/QtConcurrent>
                  #include <QApplication>
                  #include <QDateTime>
                  #include <QDebug>
                  #include <QMetaObject>
                  #include <QObject>
                  #include <QTimer>
                  
                  class PrintThreadIdTimer : public QObject
                  {
                      Q_OBJECT
                  public:
                      PrintThreadIdTimer(int interval, QObject *parent = nullptr)
                      {
                          m_timer = new QTimer(this);
                          m_timer->setInterval(interval);
                          connect(m_timer, &QTimer::timeout, this, &PrintThreadIdTimer::printThreadIdAndTimeMsecs);
                      }
                  
                      ~PrintThreadIdTimer()
                      {
                          disconnect(m_timer, &QTimer::timeout, this, &PrintThreadIdTimer::printThreadIdAndTimeMsecs);
                  
                          delete m_timer;
                          m_timer = nullptr;
                      }
                  
                      int interval()
                      {
                          return m_timer->interval();
                      }
                  
                  public slots:
                      void start()
                      {
                          m_timer->start();
                      }
                  
                      void stop()
                      {
                          m_timer->stop();
                      }
                  
                  private slots:
                      void printThreadIdAndTimeMsecs()
                      {
                          qDebug() << Q_FUNC_INFO << "ThreadId:" << QThread::currentThreadId()
                                   << "TimeMsecs:" << QDateTime::currentMSecsSinceEpoch();
                      }
                  
                  private:
                      QTimer *m_timer = nullptr;
                  };
                  
                  int main(int argc, char *argv[])
                  {
                      QApplication app(argc, argv);
                  
                      qDebug() << Q_FUNC_INFO << "Thread:" << QThread::currentThreadId()
                               << "Time:" << QDateTime::currentMSecsSinceEpoch();
                  
                      auto appRunAndExit = []()
                      {
                          PrintThreadIdTimer *printThreadTimer = new PrintThreadIdTimer(1000);
                          QThread *thread = new QThread();
                  
                          printThreadTimer->moveToThread(thread);
                  
                          QObject::connect(thread, &QThread::started, printThreadTimer, &PrintThreadIdTimer::start);
                          QObject::connect(thread, &QThread::finished, printThreadTimer, &PrintThreadIdTimer::stop);
                  
                          thread->start();
                  
                          for (int i = 0; i < 3; ++i)
                          {
                              qDebug() << Q_FUNC_INFO
                                       << "ThreadId:" << QThread::currentThreadId()
                                       << "interval():" << printThreadTimer->interval()
                                       << "Time:" << QDateTime::currentMSecsSinceEpoch();
                  
                              QThread::msleep(1000);
                          }
                  
                          thread->quit();
                          thread->wait();
                  
                          QCoreApplication::quit();
                      };
                      QThreadPool::globalInstance()->start(appRunAndExit);
                  
                      qDebug() << Q_FUNC_INFO << "-> Thread:" << QThread::currentThreadId()
                               << "Time:" << QDateTime::currentMSecsSinceEpoch();
                  
                      int out = app.exec();
                  
                      qDebug() << Q_FUNC_INFO << "---> Thread:" << QThread::currentThreadId()
                               << "Time:" << QDateTime::currentMSecsSinceEpoch();
                  
                      return out;
                  }
                  

                  Inside the lambda function I created another thread which I used it in order to move the PrintThreadIdTimer object there. I modified the class PrintThreadIdTimer in order to have start() and stop() slots to be connected with the started() and finished() signals of the thread.

                  Now, it's working as expected. I am not sure if there is a better way to do this.

                  Kind regards,

                  Stavros

                  Christian EhrlicherC Offline
                  Christian EhrlicherC Offline
                  Christian Ehrlicher
                  Lifetime Qt Champion
                  wrote on last edited by Christian Ehrlicher
                  #7

                  @Stavros-Vaionitis said in The timeout slot is not fired when the timer is called from a separate thread in the main():

                  I thought that the main event loop is accessible from all the threads th

                  Every thread has it's own event loop started inside QThread::run(): https://doc.qt.io/qt-6/qthread.html#details

                  And @JonB already told you this two posts above.

                  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
                  2
                  • S Stavros Vaionitis has marked this topic as solved on

                  • Login

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