c++ - Invoke Qt slot safe from non-qt thread
问题描述
I want to invoke a slot of 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*/
};
But because in my case boost::asio
use, with threads I don't want to have to do anything with Qt, I want to invoke this slot from a thread different from the main thread but a random thread I don't control. (On of the threads I let run boost::asio
of course)
How can I do this? QCoreApplication::postEvent
seems to be a nice choice, but the docs don't point out a nice way, on how to create the necessary QEvent
. QMetaObject::invokeMethod
with Qt::QueuedConnection
seems nice too, but isn't documented as thread safe.
So how can I safely invoke a qt slot from a non qt managed thread?
(Although the title of Boost asio with Qt suggests this could be a duplicate, the question seems completely different to me, this questions is not necessarily connected to boost::asio
)
解决方案
结果在其实现QMetaObject::invokeMethod
中Qt::QueuedConnection
实际使用QCoreApplication::postEvent
(感谢@peppe!)。但是保证它是线程安全的,当
- 与
Qt::QueuedConnection
- 由 Qt 管理的接收者的生命周期(或 AFAIK 至少直到完成调用之后)
- 除此以外,来自非主 qt 线程的收件人没有其他操作
- Qt 管理的参数的生命周期(使用 Q_ARS 或按值调用时应该没问题)
尚未记录。但是我已经创建了一个错误报告和qt 论坛讨论,似乎它是有意的,并且已经创建了一个文档更改票。
我最后用的是通用模式
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))
);
}
推荐阅读
- javascript - 如何使用节点 js 读取上传到谷歌云存储的 JSON 文件的内容
- sql - 将 SQL Server 2016 链接到 SQL Server 2000 实例
- flutter - 颤振定时器持续时间
- c++ - 如何编写单元测试
- mysql - 使用行计数聚合多行 N+1 查询
- java - 以下代码段不会产生预期结果
- postgresql - postgres_fdw:可以将数据推送到外部服务器以供加入吗?
- sql - 我可以在同一查询中单独选择列值并作为一个连接选择列值并避免冗余代码吗?
- ionicsecurity - 离子安全 SDK 版本
- c# - unknown_error_in_process 通过 IDebugControl 但通过 WinDBG 解决