繁体   English   中英

QTimer未在线程中触发

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM