【问题标题】:In a Qt app, where my worker thread is the "main" thread, how can I communicate with the GUI thread在我的工作线程是“主”线程的 Qt 应用程序中,我如何与 GUI 线程通信
【发布时间】:2014-06-13 15:09:36
【问题描述】:

通常在 Qt 应用程序中,会创建一个 QApplication,然后调用它的 exec 方法来启动 GUI 线程。

我的安排略有不同...我有自己的线程(即,不是 QThread)并且它在 I/O 上阻塞。有时,它需要向 GUI 线程发送信息。

有没有一种安全又简单的方法来做到这一点?

我看过这里:http://qt-project.org/doc/qt-5/threads-technologies.html 但没有什么能让我如此简单直接。

我在 OS X 上使用 QT5.3

【问题讨论】:

    标签: c++ multithreading qt


    【解决方案1】:

    请注意,如果您的线程不是 QThread 或者它不运行 Qt 事件循环,您将无法使用信号槽排队连接,因为排队的事件实际上不会被处理。在这种情况下,您可以像在非 Qt 应用程序中那样选择经典的信号量/互斥量同步。

    【讨论】:

    • @ratchetfreak 完全正确,你可以发送一个信号(它只是一个方法调用),但你不能收到返回,所以它只是一种方式。
    【解决方案2】:

    您可以在 QObject 上设置一个插槽并使用 QMetaObject::invokeMethod 使用默认或排队连接来确保在 QObject 的线程上调用该方法。

    也可以直接调用QObject的信号:

    class MessagePasser: public QObject{
    Q_OBJECT
    
    public:
    MessagePasser(QObject* p):QObject(p){}
    
    signals:
    void message(QByteArray);
    
    }
    

    并且在您的线程中,当您需要发送一些信息时,您可以简单地在 MessagePasser 对象上调用 message

    MessagePasser* passer;
    
    
    QByteArray data;
    //get data with blocking operation
    passer->message(data);//call signal and it will pass it to the gui thread correctly through the connected slots
    

    【讨论】:

      【解决方案3】:

      从线程安全地与 GUI 通信的唯一方法是通过信号和插槽,而您不能从自定义线程中做到这一点。 QThread 能够将其信号连接到 GUI 主线程。

      【讨论】:

      • 为什么不能使用互斥体进行线程安全通信?
      • @DominikSelzer:它不会是死锁安全的吗?您不知道 Qt 使用什么互斥锁,因此您的互斥锁及其互斥锁可能会导致您的线程和他们的线程死锁。
      【解决方案4】:

      最简单的方法是在主线程上创建一个QObject 派生类,其职责是使用信号从主线程传达事件。只要确保在主线程上实例化它。您的主线程不必是QThread

      当源和接收器在不同的线程上时,Qt 会自动使用queued connection,这意味着槽将在接收器的线程上执行。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2013-10-09
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-08-29
        • 1970-01-01
        • 2023-03-16
        • 2020-08-28
        相关资源
        最近更新 更多