我想调用MyWidget
的一个插槽
class MyWidget : public QWidget {
Q_OBJECT
public slots:
void onFooBar(const std::string&);/*std::string& could also be replaced
by a QString for easier meta system handling*/
};
但是由于我的情况使用了
boost::asio
,我不想与Qt有任何关系的线程中调用这个槽函数,我希望从一个不受我控制的随机线程中调用该槽函数。(当然其中一个线程我会让boost::asio
运行)
我该如何做?QCoreApplication::postEvent
似乎是一个不错的选择,但文档没有指出创建必要的QEvent
的好方法。QMetaObject::invokeMethod
与Qt::QueuedConnection
也很好,但没有文档说明其线程安全。
那么如何从非Qt管理的线程安全地调用qt槽函数?
(虽然Boost asio with Qt的标题表明这可能是一个重复的问题,但我认为这个问题完全不同,这个问题并不一定与boost::asio
有关)
QTimer
... - Scheff's CatQMetaObject::invokeMethod
的解决方案似乎是常见的模式,但与QCoreApplication::postEvent
相比,它没有文档化的线程安全性。因此,我已经创建了一个错误报告,在这个问题得到解决之后,我将用那个解决方案来回答这个问题。https://bugreports.qt.io/browse/QTBUG-72599 - SuperlokkusQMetaObject::invokeMethod
与排队连接一起实现是通过发布事件来实现的(请参见例如此处)。如果您查看代码,它与postEvent
一样线程安全。我不完全确定为什么没有将其记录为这样; 可能是为了避免围绕线程安全性所涉及的混淆,特别是如果涉及直接连接(“目标”对象不受安全承诺的保护!) - peppe