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;
}
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 revolves around the parent of either myClass
or classX
objects
Possibility I : myClass->moveToThread(&myClassThread); is failing
Cause: myClass has a parent already set. which is forbidden.
It means 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?
Try putting a break in the debugger, in the controller code and look at the thread id. Then put a break in the debugger in the init
method.