c++ - 从非 qt 线程调用 Qt slot safe

标签 c++ qt qt4 signals-slots qt4.8

我想调用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::invokeMethodQt::QueuedConnection 看起来也不错,但没有记录为线程安全。

那么我怎样才能从非 qt 托管线程安全地调用 qt 槽呢?

(虽然 Boost asio with Qt 的标题表明这可能是重复的,但这个问题对我来说似乎完全不同,这个问题不一定与 boost::asio 相关)

最佳答案

原来 QMetaObject::invokeMethodQt::QueuedConnection 实际上在其实现中使用了 QCoreApplication::postEvent(感谢@peppe!) .然而保证它是线程安全的,当

  1. Qt::QueuedConnection一起使用
  2. 由 Qt 管理的接收者的生命周期(或 AFAIK 至少在完成调用之前)
  3. 除了像这样来自非主 qt 线程之外,没有对收件人的其他操作
  4. 由 Qt 管理的参数的生命周期(在使用 Q_ARS 或按值调用时应该没问题)

还没有记录。但是我创建了一个 bug reportqt 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/

相关文章:

c++ - strdup 导致堆损坏

c++ - boost shared_ptr vector 成员访问

c++ - Mac OS X 上的 Qt : How to get rid of QListView's blue outline?

c++ - 指定 QMenu 的左上角位置

user-interface - 我如何添加或导入 pyqt 和 sip 到 Python

c++ - open() 中的正确路径

qt - 如何使用多个 ProgressBars 的进度数据更新 TableView?

qt - 单个项目中有多个窗口

javascript - Qt4:如何通过 QtWebkit 从 C++ 调用页面中的 JavaScript 函数?

c++ - QCalendarWidget 为 "Pop-up",而不是新窗口?