简体   繁体   English

在我的工作线程为“主”线程的Qt应用中,如何与GUI线程通信

[英]In a Qt app, where my worker thread is the “main” thread, how can I communicate with the GUI thread

Normally in a Qt app, one would create a QApplication and then call it's exec method to start the GUI thread. 通常在Qt应用程序中,将创建一个QApplication,然后调用它的exec方法以启动GUI线程。

I've got a slightly different arrangement... I have my own thread (ie, not a QThread) and it is blocking on I/O. 我的安排稍有不同...我有自己的线程(即,不是QThread),并且它阻塞了I / O。 At times, it will need to send information to the GUI thread. 有时,它需要将信息发送到GUI线程。

Is there a safe and easy way to do this? 有安全且简便的方法吗?

I looked here: http://qt-project.org/doc/qt-5/threads-technologies.html but nothing really stuck me as easy or straightforward. 我看了一下这里: http : //qt-project.org/doc/qt-5/threads-technologies.html,但是没有什么比简单或直接使我难受的了

I am using QT5.3 on OS X 我在OS X上使用QT5.3

Beware, if your thread is not QThread or it does not run Qt event loop you will not be able to use signal-slot queued connections since the queued events will not be processed actually. 请注意,如果您的线程不是QThread或它没有运行Qt事件循环,您将无法使用信号时隙排队连接,因为实际上不会处理排队事件。 In such cases you can opt for classical semaphore/mutex synchronization as you would do in non-Qt application. 在这种情况下,您可以像在非Qt应用程序中那样选择经典的信号量/互斥量同步。

You can set up a slot on a QObject and use QMetaObject::invokeMethod using the default or queued connection to ensure the method is called on the thread of the QObject. 您可以在QObject上设置一个插槽,并使用默认或排队连接使用QMetaObject::invokeMethod ,以确保在QObject的线程上调用该方法。

You can also call a signal of the QObject directly: 您还可以直接调用QObject的信号:

class MessagePasser: public QObject{
Q_OBJECT

public:
MessagePasser(QObject* p):QObject(p){}

signals:
void message(QByteArray);

}

and in your thread you can simply call message on a MessagePasser object when you need to send some info: 当您需要发送一些信息时,您可以在线程中简单地在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

The only way to communicate with the GUI from a thread safely is via signals and slots, and you cannot do that from a custom thread. 从线程安全地与GUI通信的唯一方法是通过信号和插槽,而您不能从自定义线程中进行通信。 A QThread has the abilty to connect its signals to a GUIs main thread. QThread能够将其信号连接到GUI主线程。

The easiest way to do this is to create a QObject derived class on your main thread whose responsibility is to communicate events from the main thread using signals. 最简单的方法是在主线程上创建QObject派生类,该类负责使用信号传递来自主线程的事件。 Just make sure you instantiate it on the main thread. 只要确保您在主线程上实例化它即可。 Your main thread does not have to be a QThread . 您的主线程不必是QThread

Qt will automatically use a queued connection when the source and the receiver are on different threads, which means the slot will be executed on the receiver's thread. 当源和接收者位于不同的线程上时,Qt将自动使用排队连接 ,这意味着该插槽将在接收者的线程上执行。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM