QTimer在QThread中失效

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了QTimer在QThread中失效相关的知识,希望对你有一定的参考价值。

参考技术A 通过继承QThread类重写run函数实现多线程时,在run()中开启QTimer,并连接timeout信号,会发现无法收到timeout信号,从而导致无法执行槽函数。
根据QT对QTimer的官方介绍:
In multithreaded applications, you can use “QTimer” in any thread that has an event loop. To start an event loop from a non-GUI thread, use “QThread::exec()”. Qt uses the timer's “thread affinity” to determine which thread will emit the “timeout()” signal. Because of this, you must start and stop the timer in its thread; it is not possible to start a timer from another thread.
QTimer是基于事件循环的,如果自定义线程中没有开启事件循环,那么QTimer相应的也不会起作用。QThread提供了exec()函数,可以开启事件循环,从而可以正常使用QTimer。

测试demo如下:
MyTimer类
mytimer.h

mytimer.cpp

MyThread类

MyTimer使用单例模式,在构造对象时,实例化QTimer,并通过QTimer每秒打印一个test。如果我们首先在MyThread线程中调用MyTimer::getInstance(),那么该单例对象在MyThread中构造,从而QTimer是在MyThread中创建的,如果在run()函数中没有执行exec(),那么就没有开启事件循环,导致QTimer的定时任务不起作用。当我们在run()中执行exec()后,该线程拥有event loop,便可确保QTimer正常工作。

如何在 QThread 中使用 QTimer?

【中文标题】如何在 QThread 中使用 QTimer?【英文标题】:How to use QTimer inside QThread? 【发布时间】:2012-10-10 06:59:38 【问题描述】:

我有一个类,QObject 的一个子类。我正在 QThread 中为该类创建一个实例。我想在课堂上使用 QTimer。但是计时器没有启动,因为调用者线程是一个woker线程。我该如何解决?

【问题讨论】:

在 *** 上有一个类似并已回答的问题:***.com/questions/10492480/… QThread 内部的 Tats。但是我想在一个是 qobject 的子类的类中使用,并且我的 qobject 类的实例是在 qthread 中创建的。由于我班级的调用者是 qthread,我无法在班级中使用 qtimer。 显示代码或者它没有发生! 调用者线程也是QThread的线程子类。 【参考方案1】:

好吧,你能不能在一些辅助对象中创建一个槽,该对象位于主线程中并且是该类的成员,并调度计时器的创建并从你的类开始(并且可以选择检查当前线程是否不是事件从那时起循环,在那里启动计时器是安全的)?因此,当您需要创建计时器时,您只需在主线程中向您的辅助对象发出信号,它应该可以工作。

【讨论】:

谢谢。我会试试这个。有没有可能在我的课堂上发布活动?这样 cal 就可以进入主线程,并且事件将从循环中调度吗?? 我认为这应该没问题,因为这就是它们跨越线程的插槽/信号的整个想法。但是我认为如果你的类是在一个非主线程中创建的,那么你需要记住在 helper memeber 对象上执行 moveToThread(
) ,因为那时你不会得到你需要的东西并且插槽将被调用创建类实例的线程。
谢谢!我尝试使用 moveToThread(),它满足了我的期望。

以上是关于QTimer在QThread中失效的主要内容,如果未能解决你的问题,请参考以下文章

在 QThread 中启动 QTimer

在 QTimer Singleshot 之后终止 QThread

QThread 与 QTimer 和 QSerial - 育儿

使用 QTimer、QThread 和进度条

QTimer 只能用于以 QThread 启动的线程

pyqt4:在Qthread中使用定时器Qtimer注意