使用Qt,其中工作线程创建新的GUI元素

Using Qt where worker thread creates new GUI elements

本文关键字:创建 GUI 元素 线程 工作 Qt 使用      更新时间:2023-10-16

我将保持代码简单,以便你们可以看到我正在尝试做什么;我知道所有的锁定问题,等等。我想弄清楚信号和插槽是如何与线程一起玩的。

在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();
}

假设在头文件中正确设置了信号和插槽(我已经测试过了)。现在,问题来了:

在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
}

问题是:因为MyReceiver对象是在主线程上的main()中创建的,这是否意味着插槽(例如,gott())将在主线程上运行,因此对于做GUI的东西是安全的?即使在信号是从不同的QThread引发的情况下(如本例中的MyConsole)?

是否有更好的方法允许工作线程与GUI交互(例如,Obj-C/Cocoa有一个"在主线程上发送消息"类型的方法)。Qt的方法是什么?

提前感谢!

默认情况下(Qt::AutoConnection),插槽将在创建QObject的线程中运行。因此,无论从哪个线程发出信号,槽将始终在线程中运行,QObject"生活"在其中(如果Qt事件循环在该线程中运行,否则事件无法交付)。由于主线程将成为Qt GUI线程,这将像预期的那样工作。这确实是Qt与GUI交互的方式。参见:http://doc.qt.nokia.com/4.7/thread-basics.html(查找线程亲和性)。

从一个线程发出信号并在另一个线程中接收它的"Qt方式"是使用排队连接

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

来自Qt文档::QueuedConnection:

当控制返回到接收者线程的事件循环时调用槽。插槽在接收者的线程中执行。