开发者

Using Qt where worker thread creates new GUI elements

开发者 https://www.devze.com 2023-03-31 06:41 出处:网络
I will keep the code simple so that you guys can see what I\'m trying to do ;) I am aware of all of the locking i开发者_开发知识库ssues, etc.I\'m trying to figure out how signals and slots play with t

I will keep the code simple so that you guys can see what I'm trying to do ;) I am aware of all of the locking i开发者_开发知识库ssues, etc. I'm trying to figure out how signals and slots play with threads.

In main.cpp:

int main(int argc, char *argv[]) {
    QApplication app(argc, argv);
    MyConsole c;       // Subclasses QThread and implements run()
    MyReceiver r(app); // We pass app to MyReceiver for later (see below)
    QObject::connect(&c, SIGNAL(sendit()),
                     &r, SLOT(gotit()));
    c.start();         // Start the worker thread
    app.exec();
}

Assume that the signals and slots were properly set up in the header files (I've tested and they are). Now, here's the issue:

In MyReceiver.cpp:

void MyReceiver::gotit()
{
    QLabel *label = new QLabel(0, "Hello");  // Some GUI element, any will do
    app.setMainWidget(*label);               // Some GUI action, any will do
}

The question is: Because the MyReceiver object was created in main(), which is on the main thread, does that mean that the slots (e.g., gotit()) will run on the main thread and are therefore safe for doing GUI stuff? Even in cases where the signal was raised from a different QThread (like MyConsole in this example)?

Is there a better way to allow worker threads to interact with the GUI (for example, Obj-C/Cocoa have a "send message on main thread" type of approach). What is "The Qt way" of doing this?

Thanks in advance!


By default (Qt::AutoConnection), slots will run in the thread the QObject was created in. So, no matter from what thread you emit the signal, the slot will be run always in the thread, the QObject "lives" in (if a Qt event loop is running in that thread, otherwise the event can't be delivered). Since the main thread will become the Qt GUI thread, this will work as expected. This is indeed the Qt way of interacting with the GUI. See also: http://doc.qt.nokia.com/4.7/thread-basics.html (look for thread affinity).


The "Qt way" to emit a signal from one thread and receive it in a different thread is to use a Queued connection

connect( obj, SIGNAL(foo()), other_obj, SLOT(bar()), Qt::QueuedConnection )

From the Qt documentation for Qt::QueuedConnection:

The slot is invoked when control returns to the event loop of the receiver's thread. The slot is executed in the receiver's thread.

0

精彩评论

暂无评论...
验证码 换一张
取 消