QMetaObject :: invokeMethod返回true,但从不调用方法

时间:2009-12-28 06:18:04

标签: c++ user-interface qt multithreading

我正在尝试使用QMetaObject :: invokeMethod在GUI线程上运行一个方法,该方法返回true。但是,如果我使用Qt :: QueuedConnection,我的方法永远不会被调用(即使invokeMethod返回true)。

这就是我正在使用的:

QMetaObject::invokeMethod(this, "draw_widgets", Qt::QueuedConnection)

我没有收到任何错误消息或任何内容...... 如果我使用Qt :: AutoConnection或Qt :: DirectConnection,该方法会被调用,但当然是从同一个线程调用。不是来自GUI线程,这是我需要的。

draw_widgets是void draw_widgets()类型的公共插槽 我的类继承了QObject并使用了Q_OBJECT宏。

我将非常感谢您提供的任何帮助,或者如何检查该方法未被调用的原因。

感谢。

1 个答案:

答案 0 :(得分:11)

“true”告诉您邮件已成功排队。这并不意味着排队的消息曾被处理过......

让我们说你的程序有10个线程(Thread1-Thread10)。您从Thread7排队消息。它将排队到哪个线程?何时处理此队列中的项目?

答案是每个QObject都有一个叫Thread Affinity的东西,这就是运行排队槽的线程。默认关联是指创建对象的线程(但您可以使用QObject::moveToThread()更改它。)

如果要将某些内容排入GUI线程,则this指针指定的对象应具有GUI线程的亲和性。您可以使用QObject::thread()方法进行检查。

但无论如何,无论你排队什么线程......你必须在该线程上运行某种消息泵。例如,查看QThread::exec()。如果你的线程亲和力是GUI,那么可能就是这种情况,因为你正在运行app的exec。

(作为旁注,通常不需要直接调用QMetaObject::invokeMethod。你可以创建一个信号并将其绑定到一个插槽,然后发出信号代替调用。)