【问题标题】:Using Qt where worker thread creates new GUI elements在工作线程创建新 GUI 元素的地方使用 Qt
【发布时间】:2011-11-04 20:53:43
【问题描述】:

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

在 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())将在主线程上运行,因此可以安全地执行图形用户界面的东西?即使在信号是从不同的 QThread 发出的情况下(如本例中的 MyConsole)?

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

提前致谢!

【问题讨论】:

标签: c++ multithreading qt user-interface


【解决方案1】:

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

【讨论】:

  • “无论你从哪个线程发出信号,slot 总是在同一个线程中运行” 这句话有点含糊,听起来slot 总是在同一个线程中运行信号是从那里发出的。我知道您不是这个意思(因为您的其余答案是正确的),但这可能会使其他人感到困惑。
  • 好的,那是模棱两可的,我已经改写了。感谢您的评论。
  • 应该注意,即使没有运行 exec 循环,您仍然可以发送信号。只需定期调用QCoreApplication::processEvents(),它就可以用于所有预期目的,就像您正在运行 exec 循环一样。这对于您无法将循环控制权交还给操作系统但仍需要来自不同线程的信号的输入/输出的情况非常有用。
  • 正确。 QCoreApplication::processEvents() 更适合长时间运行的操作,但如果没有事件循环(它只处理调用线程上的事件),则意义不大。
【解决方案2】:

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

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

来自 Qt::QueuedConnection 的 Qt 文档:

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-11-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-05-29
    相关资源
    最近更新 更多