首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >在QThread中启动QTimer

在QThread中启动QTimer
EN

Stack Overflow用户
提问于 2012-05-08 12:16:22
回答 6查看 45.4K关注 0票数 15

我正在尝试在特定线程中启动QTimer。但是,计时器似乎没有执行,并且没有打印输出任何内容。是与计时器、插槽还是线程有关?

main.cpp

代码语言:javascript
运行
复制
    #include "MyThread.h"
    #include <iostream>
    using namespace std;

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

MyThread.h

代码语言:javascript
运行
复制
    #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 */

MyThread.cpp

代码语言:javascript
运行
复制
    #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";
    }
EN

回答 6

Stack Overflow用户

回答已采纳

发布于 2012-05-08 14:14:51

正如我所评论的(链接中的更多信息),您这样做是错误的:

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

这部分代码应该足够了

代码语言:javascript
运行
复制
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();

现在(Qt版本>= 4.7)默认情况下,QThread在他的run()方法中启动一个事件循环。为了在线程中运行,你只需要移动对象。Read the doc...

票数 28
EN

Stack Overflow用户

发布于 2013-09-03 22:34:49

代码语言:javascript
运行
复制
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();
票数 13
EN

Stack Overflow用户

发布于 2012-05-08 12:19:03

QTimer只能在具有事件循环的线程中工作。

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

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

票数 9
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/10492480

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档