需求

在运行 qt 程序时,出了相应的警告:

QObject: Cannot create children for a parent that is in a different thread.
(Parent is QThread(0xb95feffd70), parent's thread is QThread(0x1d3729aef20), current thread is QThread(0xb95feffd70)

解决

这个其实就是在子线程中,使用了主线程的对象,并创建子对象,所以出的警告。解决的方法也有几种:

子线程创建子对象

简单说,就是在子线程中先获取主线程的相应参数,然后创建出需要的对象,这样的话,在需要创建子对象的时候,也是在同一个线程。这种方法最简单,就是代码上可能啰嗦一点。

不指定父对象

对象创建时,不指定父对象,也就是不使用 this 来指定,留空即可。如果碰到一些调用的库函数内部创建对象,这种方法就不好使了。

使用 moveToThread 绑定相应的线程

调用 QObject 的成员函数 moveToThread, 绑定到对应的线程上去。下面是几个例子:

ThreadTest2 thread2;
thread2.moveToThread(&thread2);
thread2.start();

上面这个例子,thread2 把自己从主线程绑定到子线程,这样在 ThreadTest2 这个类内部创建的对象也就转移到子线程上去了。

class Controller : public QObject
{
    Q_OBJECT

    ...

private:
    QThread thread;
};

Controller::Controller(QObject* parent)
    : QObject(parent)
{
    Worker *worker = new Worker();
    worker->moveToThread(&thread);

    ...

    thread.start();
}

上面这个例子,worker 这个类里面所有都会移交给 thread 这个线程。

参考

简单例子理解 Qt 中 QObject: Cannot create children for a parent that is in a different thread. 问题

QThread之moveToThread用法

QT 中的多线程—moveToThread 篇

QThread的用法