我想调用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
相关)
最佳答案
原来 QMetaObject::invokeMethod
和 Qt::QueuedConnection
实际上在其实现中使用了 QCoreApplication::postEvent
(感谢@peppe!) .然而保证它是线程安全的,当
- 与
Qt::QueuedConnection
一起使用 - 由 Qt 管理的接收者的生命周期(或 AFAIK 至少在完成调用之前)
- 除了像这样来自非主 qt 线程之外,没有对收件人的其他操作
- 由 Qt 管理的参数的生命周期(在使用 Q_ARS 或按值调用时应该没问题)
还没有记录。但是我创建了一个 bug report和 qt forum讨论,似乎本来就是这样的,一个documentation change ticket已经创建。
我最后用的是普通模式
class MyWidget : public QWidget {
Q_OBJECT
public slots:
void onFooBar(QString);
};
void asio_handler(const std::string& string, MyWidget* my_widget) {
QMetaObject::invokeMethod(
my_widget, "onFooBar", Qt::QueuedConnection,
Q_ARG(QString, QString::fromStdString(string))
);
}
关于c++ - 从非 qt 线程调用 Qt slot safe,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53803018/