Qt moveToThread:对象带来了哪些资源?

Posted

技术标签:

【中文标题】Qt moveToThread:对象带来了哪些资源?【英文标题】:Qt moveToThread: What resources are brought with the object? 【发布时间】:2014-10-19 16:44:20 【问题描述】:

假设我创建了一个 QObject a,它有一个成员 QObject b。 (其实A和B都是QObject的子类,A类有一个成员Bb。)

b 创建时,其父级为 0(默认)。在代码中,如果我从未将b 的父级设置为a,并且如果我调用movetothread()a 移动到工作线程中,b 也会被移动到该线程中?

如果它没有被移动,如果我从工作线程(我将a 移动到的那个)调用b.init(),它使用 new 运算符创建另一个以b 作为父级的 QObject,那么我会得到下面的错误,对吧?

QObject:无法为不同线程中的父级创建子级

【问题讨论】:

【参考方案1】:

正如 QObject::moveToThread 的 Qt 文档所述:-

更改此对象及其子对象的线程亲和性。 如果对象有父对象,则无法移动该对象。事件处理将在 targetThread 中继续进行。

在这种情况下,父对象是一个对象,其子对象可以通过在构造函数中传递父对象或通过调用子对象的 setParent 来设置。它不是具有指向另一个对象的指针的对象。

在代码中,如果我从未将 b 的父级设置为 a,并且如果我调用 movetothread() 将 a 移动到工作线程中,那么 b 也会被移动到该线程中吗?

所以,不,如果 b 的父级未设置并且您在“a”上调用 moveToThread,“b”仍将具有原始线程关联。

如果没有移动,如果我从工作线程调用 b.init()...

如果您已将 'a' 而不是 'b' 移至工作线程,则不应直接从工作线程调用 b.init。相反,工作线程中的对象 ('a') 应该发出信号,让原始线程中的对象从连接的插槽调用 b.init

【讨论】:

【参考方案2】:

b 也会被移到该线程中吗?

不,QObject 不知道ba 的成员。 (你没有说a是否持有指向b的指针,还是直接持有b,但两种情况的答案都是一样的。)

那我会得到以下错误,对吧?

QObject 的子级必须始终在拥有父级的线程中创建。我不愿意说你肯定会得到一个错误,因为行为可能是未定义的。

见Threads and QObject

【讨论】:

以上是关于Qt moveToThread:对象带来了哪些资源?的主要内容,如果未能解决你的问题,请参考以下文章

Qt源码阅读 moveToThread

qt5 通过moveToThread方式创建的线程,主线程(GUI)是不是会控制工作线程

Qt 多线程使用moveToThread

在 moveToThread() 之后未调用 Qt 4.8 信号/插槽

未调用 Qt moveToThread 插槽

Qt moveToThread 仅在第一次工作