QObject::setParent: Cannot set parent, new parent is in a different thread

我的未来我决定 提交于 2019-12-02 12:03:38

问题


Greeting

I have a following class.

class MyClass : public QObject
{
    Q_OBJECT

public:
    Q_INVOKABLE QVariant status();

public:
    MyClass(ClassX * classX);

public slots:
    void slotA();
    void slotB();

signals:
    void signalA();
    void signalB();

private:
    void init();
    void doSomething();

private:
    ClassX * classX;
    ClassA classA;
    ClassB classB;
};

In MyClass's constructor, I set classX to this.classX and in init(), I connect some of classX signals to MyClass slots and wise-versa and in someFunction() i use classA and classB.

In my controller class in main thread, I create MyClass object and run it inside different thread.

MyClass * myClass = new MyClass(classX);
connect(&myClassThread, SIGNAL(started()), myClass, SLOT(init()));
myClass->moveToThread(&myClassThread);
myClassThread.start();

I see the following warning in qDebugger.

QObject::setParent: Cannot set parent, new parent is in a different thread

Can anyone tell me why i get that warning ?

Thanks in advanced

PS 1: The classX created in main thread.

PS 2 : Remember, Everything work fine and i don't have any problem, I just want to know the reason of this warning and how to fix it.

PS 3 : I also use the following command in main thread to expose the object in javascript.

webFrame->addToJavaScriptWindowObject("myClassObject", myClass);

Edit 1 : QThread myClassThread is class member.

Edit 2 : I believe the lack of information, confused you guys and i'm sorry about that.

The constructor of MyClass is like this :

MyClass::MyClass(ClassX * classX)
{
     this.classX = classX;
}

回答1:


Let's be clear. Your code is not working as you intended it to work. That is what the framework is telling you.

QObject::setParent: Cannot set parent, new parent is in a different thread

This means all slots and signals of a certain object (suspected myClass) will not be executed in the same thread as the one expected. The issue here revolve about the parent of either myClass andclassX objects

Possibility I : myClass->moveToThread(&myClassThread); is failing

Cause: myClass has a parent already set. which is forbidden.

It mean that init() will be triggered by the thread of the thread object myClassThread. Thread-wise and event-wise, this is almost the same as if you did

MyClass * myClass = new MyClass(classX);
QMetaObject::invokeMethod(myClass, "init", Qt::QueuedConnection);

Possibility II : init() is violating thread affinity

Cause: `classX``or a mysterious related object has a parent already set or is not movable to another thread. Think widget.

moveToThread succeed, you have MyClass in one thread, and classX in another thread. You have provided classX when constructing myClass. myClass is now manipulating an object in another thread, and without further code we cannot assume thread safety or correct child parent affinity. Review MyClass::MyClass` and MyClass::init carefully.

Which One is Occurring?

Break in the debugger in controller code and look at the thread id. Then break in the debugger in the init method.

  • If it is the same thread, case I
  • Otherwise it is case II



回答2:


This is wrong in many ways:

QThread myClassThread;
MyClass * myClass = new MyClass(classX);
connect(&myClassThread, SIGNAL(started()), myClass, SLOT(init()));
myClass->moveToThread(&myClassThread);
myClassThread.start();
  1. You are creating thread object on stack not on heap! This means myClassThread object will be destroyed when this block of code ends.
  2. myClass has a parent. Object which are moved to thread can't have any parent. Only whole three of objects can be moved to threads


来源:https://stackoverflow.com/questions/35868750/qobjectsetparent-cannot-set-parent-new-parent-is-in-a-different-thread

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!