QTimer不在线程中触发

时间:2014-08-10 00:42:57

标签: c++ qt qthread qtimer

我有一个带有2个线程的Qt5 c ++应用程序,主程序启动时启动了线程A.线程A的start方法成功运行。

到目前为止一切顺利。接下来,在主程序中,我向线程A发送一个信号以启动QTimer,它会执行 - 但该计时器永不过期!

线程B处理tcp连接。当我启动到我的应用程序的telnet连接时,线程B激活,突然我看到我的Qtimer从线程A正常到期。

为什么线程A的QTimer在线程B启动之前没有到期?

我怀疑我的线程搞砸了。请注意以下代码的最后一部分产品:

thread of this:  QThread(0x200fe00)  
thread of timer:  QThread(0x1fff470)

这表明我的worker对象(this)与我的timer对象位于不同的线程中。此计时器线程地址实际上是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();

2 个答案:

答案 0 :(得分:1)

嗯,这不是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/

我希望它会有所帮助;)

答案 1 :(得分:-1)

最佳答案似乎是RobbieE和Kuba的结合:

您必须在构造函数中显式设置成员变量的父级。父子特征是从QObject派生的类中存在的Qt事物,它不是C ++的特征。

我从来不知道这一点 - 我假设在创建对象时,其成员变量会自动将其父对象设置为对象。很高兴知道!!