【发布时间】:2019-05-17 02:23:20
【问题描述】:
我想调用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有关)
【问题讨论】:
-
我只记得我曾经做过类似的事情(不知何故):SO: Qt C++ Displaying images outside the GUI thread (Boost thread)。可能是,今天我会使用已发布的事件而不是
QTimer... -
@Scheff 使用
QMetaObject::invokeMethod的解决方案似乎是常见模式,但与QCoreApplication::postEvent相比,没有记录线程安全。为此,我创建了一个错误报告,解决此问题后,我将使用该解决方案自行回答。 bugreports.qt.io/browse/QTBUG-72599 -
QMetaObject::invokeMethod与队列连接是在发布事件方面实现的(参见例如here)。如果您查看代码,它与postEvent一样是线程安全的。我不完全确定为什么没有这样记录;可能是为了避免混淆线程安全指的是什么,尤其是。如果涉及直接连接(“目标”对象不在安全承诺范围内!) -
codereview.qt-project.org/#/c/248378 添加文档的相关位。
标签: c++ qt qt4 signals-slots qt4.8