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

时间:2011-08-26 21:49:44

标签: c++ multithreading qt user-interface

我会保持代码简单,以便你们可以看到我正在尝试做的事情;) 我知道所有的锁定问题,等等。我正在试图找出信号和插槽如何与线程一起使用。

在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()中创建的,它位于主线程上,这是否意味着插槽(例如,gotit())将在主线程上运行,因此可以安全地执行GUI的东西?即使在信号来自不同的QThread的情况下(例如本例中的MyConsole)?

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

提前致谢!

2 个答案:

答案 0 :(得分:5)

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

答案 1 :(得分:2)

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

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

来自Qt :: QueuedConnection的Qt文档:

  

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

相关问题