代码之家  ›  专栏  ›  技术社区  ›  Superlokkus

从非qt线程安全调用qt槽

  •  0
  • Superlokkus  · 技术社区  · 6 年前

    我想调用 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做任何事情的线程,我想从一个不同于主线程但我不控制的随机线程调用这个槽。(在我放的线上) 升压: 当然)

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

    那么,如何从非qt托管线程安全地调用qt槽呢?

    (尽管 Boost asio with Qt 暗示这可能是一个复制品,这个问题对我来说似乎完全不同,这个问题不一定与 升压: )

    1 回复  |  直到 6 年前
        1
  •  0
  •   Superlokkus    6 年前

    转出 QMetaObject::invokeMethod 具有 Qt::QueuedConnection 实际使用 QCoreApplication::postEvent 在它的实现中(谢谢@peppe!)但是,当

    1. 用于 qt::队列连接
    2. 由qt(或afaik)管理的接收者的生存期,至少在完成调用之前
    3. 除此之外,从非主qt线程对收件人没有其他操作
    4. 由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))
                            );
    }