[英]QTimer not firing in a thread
我有一个带有2个线程的Qt5 c ++应用程序,主程序启动时启动了线程A。 线程A的启动方法成功运行。
到现在为止还挺好。 接下来,在主程序中,我向线程A发送一个信号以启动QTimer,它确实可以-但是该计时器永不过期!
线程B处理tcp连接。 当我启动与应用程序的telnet连接时,线程B启动,突然我看到线程A的Qtimer以正常间隔过期。
为什么直到线程B启动,线程A的QTimer才到期?
我怀疑我的线程弄乱了。 请注意下面的代码的最后一部分,该产品是:
thread of this: QThread(0x200fe00)
thread of timer: QThread(0x1fff470)
这表明我的工作程序对象(this)与计时器对象处于不同的线程中。 此计时器线程地址实际上是MAIN线程。 为什么? 我糊涂了。
有什么建议吗?
在我的主应用程序中,我这样创建并启动线程:
QThread * MyControllerThread = new QThread(this);
if (MyControllerThread) {
TheController *worker = new TheController(MyControllerThread);
if (worker) {
connect(MyControllerThread, SIGNAL(started()), worker, SLOT(start()));
connect(MyControllerThread, SIGNAL(finished()), worker, SLOT(deleteLater()));
connect(MyControllerThread, SIGNAL(finished()), MyControllerThread, SLOT(deleteLater()));
worker->moveToThread(MyControllerThread);
MyControllerThread->start();
}
在主应用程序中,我向新线程发出信号:
emit sig_startlocalpeer(Types::EActionLocalServiceStart); // Move the local peer to standby mode to start remote tests
它在我的线程(TheController对象)中运行一个插槽:
connect(&m_remotetestintervaltimer,SIGNAL(timeout()),this,SLOT(expiredRemoteTestIntervalTimer()));
m_remotetestintervaltimer.setTimerType(Qt::VeryCoarseTimer);
m_remotetestintervaltimer.start(REMOTETEST_TIMER_INTERVAL); // Wait between ticks
qDebug() << "thread of this: " << this->thread();
qDebug() << "thread of timer: " << m_remotetestintervaltimer.thread();
好吧,这不是Qt5的错误,而是对Qt的线程精神的不准确的了解。
在Qt中,有两种实现线程的方法,它们使用的是偶数循环,也可以不使用偶数循环。 这只是一个小的视觉示例。
没有事件循环
myMethodCalledInANewThread
{
do{ ... }while(...);
}
具有事件循环
myMethodCalledInANewThread
{
[...]
exec();
}
(当然,您可以将一个do / while与一个偶数循环混合在一起,但保持简单)。
在QTimer的文档中,您可以阅读:
在多线程应用程序中,可以在具有事件循环的任何线程中使用QTimer。 [...] Qt使用计时器的线程关联性来确定哪个线程将发出timeout()信号。 因此,您必须在其线程中启动和停止计时器。 无法从另一个线程启动计时器。
因此,我非常确定您在第二个线程中没有第二个事件循环,这就是您具有所描述的行为的原因。
为了给您一些使用Qt完全清楚了解线程的提示,建议您阅读以下内容:
一篇非常好的文章,介绍了许多用户如何误解QThread实现。 -您做错了: http : //blog.qt.digia.com/blog/2010/06/17/youre-doing-it-wrong/
我希望它会有所帮助;)
最好的答案似乎是RobbieE和Kuba的结合:
您必须在构造函数中显式设置成员变量的父级。 父子功能是Qt事物,它存在于从QObject派生的类中,而不是C ++的功能。
我从来不知道这一点-我假设创建对象时,其成员变量会自动将其父对象设置为该对象。 很高兴知道!!
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.