从 non-qt 线程调用 Qt 槽安全
Invoke Qt slot safe from non-qt thread
我想调用 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 and qt forum discussion, and it seems it was intended to be so, and a 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))
);
}
我想调用 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 and qt forum discussion, and it seems it was intended to be so, and a 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))
);
}