在非Qt线程或者Qt主事件循环之外,如何使用4.5版本发出Qt信号?

12

我正在从一个非Qt线程中调用emit signal1()

所谓的非Qt线程是指不来自GUI事件循环,也不来自任何QThread的run()方法或任何QThread自己的事件循环。

这只是一个调用QObject方法并发出信号的pthread(pthread_create())。

例如:

MyQbject: public QObject
{
...
void emitBunchOfSignals()
{
 emit signal1();
 emit signal2();
 ...
}
...
}

我的pthread的"run"方法有一个指向MyObject实例的指针(该实例是在主Qt GUI线程上下文中创建而不是pthread内部),调用emitBunchOfSignals()方法。

在Qt 4.5之前,这很恶心。现在,Qt 4.5是否处理了这个问题?它是否调用qApp->PostEvent()或其他类似方法以便在Qt GUI线程中发出信号(因此也会触发槽)?

谢谢


当您调用connect时,可能会显式设置类型为排队连接。 - Kaleb Pederson
在你写下这个问题的时间里,你本可以打开代码自己看看。 - shoosh
它似乎不像以前那样直截了当,因为在Qt 3.xx中它会崩溃。 我熟悉connect选项(directconnection queuedconnection等),但我认为它只在QTreads之间或在QThread和主事件循环之间起作用。至少在Qt 3.xx中为什么会崩溃并不容易通过查看代码来理解。难道我疯了吗? - Nicolas Robert
@Nicolas - 一些线程代码和必要的背景使得很难轻松理解正在发生的事情。需要浏览很多内容,如线程池、moc等。 - Kaleb Pederson
1个回答

9

你需要确保使用排队连接到线程,因为Qt无法自动识别哪个对象属于哪个线程(文档中使用“线程亲和性”一词)。在连接时进行如下操作:

connect(src, SIGNAL(signal-signature), dest, SLOT(slot-signature), Qt::QueuedConnection);

这将导致信号被放置在目标的事件循环中,并且当其线程正在运行(即其事件循环)时调用该槽。


3
为了确保我理解您的意思: 由于我发出信号的QObject既不属于QThread也不属于主Qt GUI线程(实际上它属于我的Corba线程),因此Qt无法感知线程亲和性。因此,我必须强制连接到QueuedConnection,因为在这种特定情况下AutomaticConnection不起作用。 但是,当发出信号的QObject属于QThread时,Qt可以感知线程亲和性,并且automaticConnection将对接收器QObject线程的事件循环进行必要的后续处理。 - Nicolas Robert

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接