如果我理解正确,插槽将始终出现在主线程中。
那么使用信号槽系统和moveToThread(qApp->thread())
之间有什么区别?
答案 0 :(得分:2)
您的理解不正确。
每个线程都有自己的事件队列,因此当发出信号时,如果连接排队(非直接),它将被添加到与对象的线程关联性匹配的事件队列中。
例如: -
假设我们有2个对象;在主线程上运行的 object1 和 object2 ,它已被移动到新线程。
connect(object1, &SomeObject::signal1, object2, &SomeOtherObject::signal2);
当 object1 发出 signal1 时,会向新线程发布一个事件; object2 被移动到的线程。
当新线程处理其事件循环和 signal1 的事件时,它将执行 object2 的插槽, signal2 。这不在主线上。
答案 1 :(得分:0)
可以将每个QObject
树分配给指定的主题。 moveToThread
表示将对象树(对于给定的根对象)移动到该线程。
这并不意味着QObject
的所有代码都分配给该线程。这意味着将在给定线程中调用由排队连接(非直接连接)调用的任何插槽。仔细阅读QObject::connect和Qt::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将再次被删除。