从非Qt线程调用Qt插槽安全

时间:2018-12-16 14:18:50

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

我要调用sudo apt install ubuntu-restricted-extra 的广告位

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*/ }; 使用线程,我不想对Qt做任何事情,所以我想从不同于主线程的线程调用此插槽,但是我不使用随机线程无法控制。 (我当然在其中运行boost::asio的线程中)

我该怎么做? boost::asio似乎是一个不错的选择,但文档并未指出如何创建必要的QCoreApplication::postEvent的好方法。 QEventQMetaObject::invokeMethod看起来也不错,但是没有记录为线程安全。

那我如何从非qt托管线程安全地调用qt插槽?

(尽管Boost asio with Qt的标题表明这可能是重复的,但问题对我而言似乎完全不同,此问题不一定与Qt::QueuedConnection有关)

1 个答案:

答案 0 :(得分:0)

QMetaObject::invokeMethodQt::QueuedConnection一起使用,实际上在其实现中使用QCoreApplication::postEvent(感谢@peppe!)。但是,当

时,保证它是线程安全的
  1. Qt::QueuedConnection
  2. 一起使用
  3. 由Qt管理的收件人的生命周期(或至少在完成调用后由AFAIK管理)
  4. 从非主qt线程对接收者进行的其他操作除外,
  5. 由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))
                        );
}