存在许多类似的问题,但找不到合适的答案。
我使用第三方图书馆。
当一些对LIB的类的虚方法被调用,这些都是从已经工作者线程调用没有被启动通过我的应用程序。这个线程不是QThread,也永远不可能。
我可以从该线程发出信号,但前提是必须使用Qt :: DirectConnection连接插槽。结果是SLOT中的QObject :: sender()将始终返回NULL。例如,我希望调用deleteLater(),但是只能在QThread中进行调度。
我想我需要回到主线程,但是如何在主线程上发信号通知对象呢?
示例:调用下面的方法时,它是在第3方库创建的线程上完成的。
/*virtual*/ bool MediaPlayer::onEof()
{
stopTransmit();
emit sigFinished(); // slots only called if bound using Qt::DirectConnection
deleteLater(); // dtor is never called
return false;
}
连接也是从非QThread上下文中进行的,如下所示:
/*virtual*/ void
SipCall::state_answer_call::onEntering(SipCall& ref)
{
...
MediaPlayer* player = new MediaPlayer;
ref.connect(player, SIGNAL(sigFinished()), SLOT(slotMediaFinished()), Qt::DirectConnection);
...
}
没有显式的Qt::DirectConnection
,SipCall::slotMediaFinished()
永远不会被调用。
当调用库类上的某些虚拟方法时,这些虚拟方法是从尚未由我的应用程序启动的工作线程中调用的。这个线程不是QThread,也永远不可能。
有人错误地认为这是一个问题。它不是。发出信号的线程无关紧要。不必开始使用QThread
。
实际上,从C回调发出信号是将多线程C回调API与Qt接口的惯用方式。它旨在不费吹灰之力地工作。
我可以从该线程发出信号,但前提是必须使用Qt :: DirectConnection连接插槽。
这不是真的。当信号和插槽位于不同的线程中时,如果连接的插槽/功能部件是线程安全的,则只能使用直接连接。我怀疑你是,那么你应该不使用直接连接。自动连接将完全满足您的需求。
它不起作用,因为接收SipCall
实例不存在于具有正在运行的事件循环的线程中。您必须将其移动到这样的线程中,或者使用GM对此问题的回答中所建议的,位于主线程中的thunk函子。
泛函仿函数的问题在于它们混淆了您要在其上调用方法的对象的线程所有权。最有可能的SipCall
方法不是线程安全的要么,所以由你一定会打破东西主线程调用它们。将播放器移至应用程序线程,并确保仅在该线程中使用它是最安全的。那时您将不需要笨重的函子。
如果要查看在给定线程中运行某些代码(例如函子)的方式,请参阅此问题。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句