在QThread中启动QTimer

Tud*_*scu 15 c++ qt multithreading timer qthread

我试图在特定的线程中启动QTimer.但是,计时器似乎没有执行,也没有打印出来.是与计时器,插槽还是线程有关?

main.cpp中

    #include "MyThread.h"
    #include <iostream>
    using namespace std;

    int main(int argc, char *argv[]) {
        MyThread t;
        t.start();
        while(1);
    }
Run Code Online (Sandbox Code Playgroud)

MyThread.h

    #ifndef MYTHREAD_H
    #define MYTHREAD_H

    #include <QTimer>
    #include <QThread>
    #include <iostream>

    class MyThread : public QThread {
        Q_OBJECT
    public:
        MyThread();
    public slots:
        void doIt();
    protected:
        void run();
    };

    #endif  /* MYTHREAD_H */
Run Code Online (Sandbox Code Playgroud)

MyThread.cpp

    #include "MyThread.h"

    using namespace std;

    MyThread::MyThread() {
        moveToThread(this);
    }

    void MyThread::run() {
        QTimer* timer = new QTimer(this);
        timer->setInterval(1);
        timer->connect(timer, SIGNAL(timeout()), this, SLOT(doIt()));
        timer->start();
    }

    void MyThread::doIt(){
        cout << "it works";
    }
Run Code Online (Sandbox Code Playgroud)

UmN*_*obe 24

正如我评论的那样(链接中的更多信息),你做错了:

  1. 您正在将持有线程数据的对象与另一个对象(负责doIt())混合.他们应该分开.
  2. QThread在您的情况下不需要子类.更糟糕的是,你在run没有考虑它正在做什么的情况下重写方法.

这部分代码应该足够了

QThread* somethread = new QThread(this);
QTimer* timer = new QTimer(0); //parent must be null
timer->setInterval(1);
timer->moveToThread(somethread);
//connect what you want
somethread->start();
Run Code Online (Sandbox Code Playgroud)

现在(Qt版本> = 4.7)默认情况下QThread在他的run()方法中启动一个事件循环.要在线程内运行,只需移动对象即可.阅读文档......

  • 将信号连接到计时器插槽“ start()”并触发信号 (2认同)

And*_*urg 12

m_thread = new QThread(this);
QTimer* timer = new QTimer(0); // _not_ this!
timer->setInterval(1);
timer->moveToThread(m_thread);
// Use a direct connection to whoever does the work in order
// to make sure that doIt() is called from m_thread.
worker->connect(timer, SIGNAL(timeout()), SLOT(doIt()), Qt::DirectConnection);
// Make sure the timer gets started from m_thread.
timer->connect(m_thread, SIGNAL(started()), SLOT(start()));
m_thread->start();
Run Code Online (Sandbox Code Playgroud)

  • @Stormenet一个带有插槽`doIt()`的对象,应该在计时器触发时执行工作(在创建的线程中). (2认同)

Bri*_*ach 9

A QTimer仅适用于具有事件循环的线程.

http://qt-project.org/doc/qt-4.8/QTimer.html

在多线程应用程序中,您可以在任何具有事件循环的线程中使用QTimer.要从非GUI线程启动事件循环,请使用QThread :: exec().Qt使用计时器的线程亲和性来确定哪个线程将发出timeout()信号.因此,您必须在其线程中启动和停止计时器; 无法从另一个线程启动计时器.