我正在使用Qt开发一个应用程序,我希望从另一个不相关的类更新我的GUI,并在不同的线程中执行函数。
我使用标准C ++构造std :: function和std :: bind在Qt GUI类中向另一个类注册了一个回调函数。
在尝试从其他类执行GUI回调函数时,我的程序崩溃,“ qt无法将事件发送到不同线程拥有的对象”。
我的问题是,这里发生了什么。为什么不允许这样的两个线程之间进行通信。是否有可能以某种方式解决这个问题,或者Qt是否不允许其他不相关的函数以这种方式更新GUI?
有关信息,我在Windows上使用portaudio库。它在不同的线程中执行回调。当我收到音频时,我会尝试更新我的GUI。
提前谢谢
答案 0 :(得分:2)
你可能会被“发送事件”这句话甩掉。在Qt中,这个短语具有严格的技术含义。即:
到发送事件意味着使用QCoreApplication::sendEvent
,然后会立即在接收方上调用QObject::event
。 发送和接收线程不同时发送事件是错误的。
到发布事件意味着使用QCoreApplication::postEvent
,它将事件发布到接收对象线程的事件队列。接收器线程的事件循环稍后调用接收器上的QObject::event
。
当对象生活在不同的主题中时,您不能发送事件,只能发布。这指出了您的问题的根本原因/
您在QWidget
或派生类上访问的任何方法都必须在其thread()
上访问,即主线程。 QWidget
内的所有内容都可以自由使用sendEvent
,因为发送线程和接收对象的线程在合同中是相同的。通过从错误的线程调用QWidget
方法,您可以通过间接使用sendEvent
来破坏该合同,从而失败。
只有您自己实现并且线程安全的方法可以从其他线程调用 - 并且它们不能使用sendEvent
。