我有一个带有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();
答案 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 ++的特征。
我从来不知道这一点 - 我假设在创建对象时,其成员变量会自动将其父对象设置为对象。很高兴知道!!