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. QTimer cannot in QThread
QtWS25 Last Chance

QTimer cannot in QThread

Scheduled Pinned Locked Moved General and Desktop
10 Posts 6 Posters 6.7k 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.
  • DongMKD Offline
    DongMKD Offline
    DongMK
    wrote on last edited by
    #1

    QTimer cannot timeout in the QThread.
    qDebug() don't print anything
    and don't run in to Thread::updateLog().
    but QTimer::singleShot() work fine.

    //thread.h
    #ifndef THREAD_H
    #define THREAD_H
    
    #include <QThread>
    #include <QTimer>
    
    class Thread : public QThread
    {
        Q_OBJECT
    public:
        explicit Thread(QObject *parent = 0);
    protected:
        void run();
    signals:
    
    public slots:
        void updateLog();
    private:
        QTimer *m_timer;
    };
    
    #endif // THREAD_H
    
    //thread.cpp
    #include "thread.h"
    #include <QDebug>
    
    Thread::Thread(QObject *parent) : QThread(parent)
    {
        m_timer = new QTimer(0);
        m_timer->setInterval(0);
        m_timer->moveToThread(this);
    }
    
    void Thread::updateLog()
    {
        qDebug()<<"update!";
    }
    
    void Thread::run()
    {
        m_timer->start(1000);
        //QTimer::singleShot(0, this , &Thread::updateLog);
    }
    
    //main.cpp
    #include "widget.h"
    #include "thread.h"
    #include <QApplication>
    int main(int argc, char *argv[])
    {
        QApplication a(argc, argv);
        Widget w;
        w.show();
        Thread thread;
        thread.start();
        return a.exec();
    }
    
    1 Reply Last reply
    0
    • m.sueM Offline
      m.sueM Offline
      m.sue
      wrote on last edited by
      #2

      Hi,
      in this code you did not connect the timer's timeout signal to the updateLog slot.
      -Michael.

      1 Reply Last reply
      3
      • SGaistS Offline
        SGaistS Offline
        SGaist
        Lifetime Qt Champion
        wrote on last edited by
        #3

        Hi,

        To add to @m-sue, your thread won't start an event loop either, so even if you slots gets invoked it won't be in the correct thread.

        Please take a look at QThread's detailed documentation for the correct usage of this class

        Interested in AI ? www.idiap.ch
        Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

        DongMKD 1 Reply Last reply
        2
        • SGaistS SGaist

          Hi,

          To add to @m-sue, your thread won't start an event loop either, so even if you slots gets invoked it won't be in the correct thread.

          Please take a look at QThread's detailed documentation for the correct usage of this class

          DongMKD Offline
          DongMKD Offline
          DongMK
          wrote on last edited by
          #4

          thank you @SGaist @m-sue .
          when I add exec() , QTimer work fine.
          I am curiosity about why QTimer::singleShot() work fine.

          A 1 Reply Last reply
          0
          • DongMKD DongMK

            thank you @SGaist @m-sue .
            when I add exec() , QTimer work fine.
            I am curiosity about why QTimer::singleShot() work fine.

            A Offline
            A Offline
            ambershark
            wrote on last edited by
            #5

            @DongMK said in QTimer cannot in QThread:

            thank you @SGaist @m-sue .
            when I add exec() , QTimer work fine.
            I am curiosity about why QTimer::singleShot() work fine.

            I believe the answer here is because singleShot() doesn't use signals/slots. It calls the function you pass directly after the timeout happens. But I am not 100% sure about that so confirm for yourself in the code if you're really curious. :)

            My L-GPL'd C++ Logger github.com/ambershark-mike/sharklog

            1 Reply Last reply
            0
            • BuckwheatB Offline
              BuckwheatB Offline
              Buckwheat
              wrote on last edited by
              #6

              I you create your timer in the "run" method, you do not have to "moveToThread". The timer will be in the thread space. As @SGaist said there is good documentation on using threads. You will see two flavors:

              1. is the way you did. Derive from QThread and extend it for arbitrary work (not very OO since you are really not creating a new type of thread like a PeriodicThread or SyncedThread).
              2. QThread as a worker as in the documentation.

              Both, are equally valid if you do not care about OOness but I am finding the newer way much easier now that I have played with it more.

              And, as always, if you want signal/slot methods to work across your thread bounds, you need to keep the event loop running. Signals are always queued when emitted across thread bounds. So, since your singleShot was done inside the thread boundary, it was NOT queued but the signal acted as a function call.

              Dave Fileccia

              jsulmJ 1 Reply Last reply
              1
              • BuckwheatB Buckwheat

                I you create your timer in the "run" method, you do not have to "moveToThread". The timer will be in the thread space. As @SGaist said there is good documentation on using threads. You will see two flavors:

                1. is the way you did. Derive from QThread and extend it for arbitrary work (not very OO since you are really not creating a new type of thread like a PeriodicThread or SyncedThread).
                2. QThread as a worker as in the documentation.

                Both, are equally valid if you do not care about OOness but I am finding the newer way much easier now that I have played with it more.

                And, as always, if you want signal/slot methods to work across your thread bounds, you need to keep the event loop running. Signals are always queued when emitted across thread bounds. So, since your singleShot was done inside the thread boundary, it was NOT queued but the signal acted as a function call.

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

                @Buckwheat @DongMK I think it would be better to create the timer in run(). If you do it in the constructor then you have to move it to the thread as the constructor is not executed in the new thread - new thread starts when you call thread.start(); But in constructor it makes no sence to call moveToThread() as the new thread is not yet started.
                It would be even better to allocate the timer on the stack - in this case there is no need to move it to the right thread as it will be moved together with your Thread instance. Why do you allocate the timer on the heap? Why don't you free the timer in destructor?

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

                BuckwheatB DongMKD 2 Replies Last reply
                0
                • jsulmJ jsulm

                  @Buckwheat @DongMK I think it would be better to create the timer in run(). If you do it in the constructor then you have to move it to the thread as the constructor is not executed in the new thread - new thread starts when you call thread.start(); But in constructor it makes no sence to call moveToThread() as the new thread is not yet started.
                  It would be even better to allocate the timer on the stack - in this case there is no need to move it to the right thread as it will be moved together with your Thread instance. Why do you allocate the timer on the heap? Why don't you free the timer in destructor?

                  BuckwheatB Offline
                  BuckwheatB Offline
                  Buckwheat
                  wrote on last edited by
                  #8

                  @jsulm I did say that ... "I [sic] you create your timer in the "run" method..."

                  Multi-threading can be daunting when it comes to thread-local storage and "other" storage. That is why the newer documentation makes more sense. The object, and all its members, will be moved to the thread and as long as the thread event queue is processed, there are really few limitations.

                  I suggest you start small and get used to the worker thread concept. You can actually create a nice worker thread base class, say... WTObject to attach all the little signals/slots for started, finished, etc.

                  Dave Fileccia

                  DongMKD 1 Reply Last reply
                  0
                  • jsulmJ jsulm

                    @Buckwheat @DongMK I think it would be better to create the timer in run(). If you do it in the constructor then you have to move it to the thread as the constructor is not executed in the new thread - new thread starts when you call thread.start(); But in constructor it makes no sence to call moveToThread() as the new thread is not yet started.
                    It would be even better to allocate the timer on the stack - in this case there is no need to move it to the right thread as it will be moved together with your Thread instance. Why do you allocate the timer on the heap? Why don't you free the timer in destructor?

                    DongMKD Offline
                    DongMKD Offline
                    DongMK
                    wrote on last edited by
                    #9

                    @jsulm I search "why QTimer cannot work in QThread" on baidu.com . And all answer is :

                        m_timer = new QTimer(0);
                        m_timer->setInterval(0);
                        m_timer->moveToThread(this);
                    

                    ,so I try to use it.

                    I write the code which in this topic just want to show the problem for me, so it not perfect.

                    1 Reply Last reply
                    0
                    • BuckwheatB Buckwheat

                      @jsulm I did say that ... "I [sic] you create your timer in the "run" method..."

                      Multi-threading can be daunting when it comes to thread-local storage and "other" storage. That is why the newer documentation makes more sense. The object, and all its members, will be moved to the thread and as long as the thread event queue is processed, there are really few limitations.

                      I suggest you start small and get used to the worker thread concept. You can actually create a nice worker thread base class, say... WTObject to attach all the little signals/slots for started, finished, etc.

                      DongMKD Offline
                      DongMKD Offline
                      DongMK
                      wrote on last edited by
                      #10

                      @Buckwheat I'm poor in english and QThread. I can not understand whole your meaning. I will read the QThread's Document and correct my error.

                      1 Reply Last reply
                      0

                      • Login

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