moveToThread(qApp-> thread())和signal-slot

时间:2015-08-17 09:23:17

标签: qt signals-slots

如果我理解正确,插槽将始终出现在主线程中。 那么使用信号槽系统和moveToThread(qApp->thread())之间有什么区别?

3 个答案:

答案 0 :(得分:2)

您的理解不正确。

每个线程都有自己的事件队列,因此当发出信号时,如果连接排队(非直接),它将被添加到与对象的线程关联性匹配的事件队列中。

例如: -

假设我们有2个对象;在主线程上运行的 object1 object2 ,它已被移动到新线程。

connect(object1, &SomeObject::signal1, object2, &SomeOtherObject::signal2);

object1 发出 signal1 时,会向新线程发布一个事件; object2 被移动到的线程。

当新线程处理其事件循环和 signal1 的事件时,它将执行 object2 的插槽, signal2 。这不在主线上。

答案 1 :(得分:0)

可以将每个QObject 分配给指定的主题。 moveToThread表示将对象树(对于给定的根对象)移动到该线程。

这并不意味着QObject的所有代码都分配给该线程。这意味着将在给定线程中调用由排队连接(非直接连接)调用的任何插槽。仔细阅读QObject::connectQt::ConnectionType的文档。

除了Qt::DirectConnection之外,所有连接都使用接收对象的拥有线程来传递信号。所有参数都被打包并发送到接收者的事件队列。当接收线程的事件循环获得控制时,它将解包参数并调用插槽。

请注意,我在上面写了一篇关于对象树的文章。如果对象具有父对象,则无法将对象移动到其他线程。并且您无法将对象重新显示为属于不同线程的对象。

默认情况下,对象被分配给创建它们的线程(如果它们没有父对象)。所以它不一定是主线程。

答案 2 :(得分:0)

Thread a,b,c;
a created b,  b created c;
connect(a, &QThread::finished, a, &QObject::deleteLater);
connect(b, &QThread::finished, b, &QObject::deleteLater);
connect(c, &QThread::finished, c, &QObject::deleteLater);

我做了一些实验,发现如果b比c完成得快,c就不会被删除;但是可以这样做:     B-> moveObject(a)的//然后b将再次被删除。