Error: QObject::setParent: Cannot set parent, new parent is in a different thread
-
I have a Left class and a CleaningThread class, which is a private member of the Left class. Now, I have a cleanValvesPerPage function in my Left class. I am calling this function by overriding the run method of CleaningThread class. This thread starts when a certain Clean button is clicked.
Now, after cleaning the valves on the current page, the onNextButtonClicked() slot is called. But, this slot is present in the Left class. Due to this, I am getting this error: QObject::setParent: Cannot set parent, new parent is in a different thread. So, the program ends unexpectedly at this point.
If someone has faced the same issue and could guide me towards an alternate approach, it would be very helpful.This is my CleaningThread class implementation:
private: class CleaningThread : public QThread { public: CleaningThread(Left *parent); void startCleaning(); void stopCleaning(); protected: void run() override; private: Left *parentLeft; std::atomic<bool> stop; };
This is my onCleanButtonClicked() function:
void Left::onCleanButtonClicked() { cleaningThread = new CleaningThread(this); cleaningThread->startCleaning(); connect(cleaningThread, SIGNAL(finished()), this, SLOT(onCleaningFinished())); cleaningThread->start(); }
-
Hi,
What are you doing in that class ?
It looks like you are trying to reparent stuff when you should not.Based on the names, you might even be trying to access GUI elements from a different thread which is forbidden.
-
Hi,
What are you doing in that class ?
It looks like you are trying to reparent stuff when you should not.Based on the names, you might even be trying to access GUI elements from a different thread which is forbidden.
@SGaist
Thank you for your reply!I am trying to run a particular function cleanValvesOnPage through the CleaningThread class.
This is how I am overriding the run() function of the CleaningThread class:
void Left::CleaningThread::run() { int startIndex = parentLeft->currentIndex; parentLeft->cleanValvesOnPage(startIndex); parentLeft->cleaningThread = nullptr; }
If I can't access GUI elements through a different thread then is there any alternative approach to do it without having the risk of freezing the ui?
-
@SGaist
Thank you for your reply!I am trying to run a particular function cleanValvesOnPage through the CleaningThread class.
This is how I am overriding the run() function of the CleaningThread class:
void Left::CleaningThread::run() { int startIndex = parentLeft->currentIndex; parentLeft->cleanValvesOnPage(startIndex); parentLeft->cleaningThread = nullptr; }
If I can't access GUI elements through a different thread then is there any alternative approach to do it without having the risk of freezing the ui?
Send a signal to a slot and execute the function there?!
-
Send a signal to a slot and execute the function there?!
@Pl45m4
Actually, signals and slots are not supported in nested classes in Qt. -
@Pl45m4
Actually, signals and slots are not supported in nested classes in Qt.What "nested" classes? Your use case is the perfect example of forcing the use of any thread related stuff when it's not needed at all...
What should yourcleaningThread
do? Modify the GUI? Direct or access via signals never blocks unless you add some blocking loops.
So I think you should re-design your app structure -
What "nested" classes? Your use case is the perfect example of forcing the use of any thread related stuff when it's not needed at all...
What should yourcleaningThread
do? Modify the GUI? Direct or access via signals never blocks unless you add some blocking loops.
So I think you should re-design your app structure@Pl45m4
Okay, I got your point. Basically, I was trying to update the GUI by using the cleaningThread. But now, I am just passing a signal in the run() method of the cleaningThread. This signal connects to the appropriate slot and does the cleaning action. Please let me know if this is the correct approach or I am still missing on something? -
@Pl45m4
Okay, I got your point. Basically, I was trying to update the GUI by using the cleaningThread. But now, I am just passing a signal in the run() method of the cleaningThread. This signal connects to the appropriate slot and does the cleaning action. Please let me know if this is the correct approach or I am still missing on something?@shreya_agrawal is this the real code of your application ? Because using a thread to just trigger a GUI update is more than overkill.
-
@Pl45m4
Okay, I got your point. Basically, I was trying to update the GUI by using the cleaningThread. But now, I am just passing a signal in the run() method of the cleaningThread. This signal connects to the appropriate slot and does the cleaning action. Please let me know if this is the correct approach or I am still missing on something?@shreya_agrawal said in Error: QObject::setParent: Cannot set parent, new parent is in a different thread:
Please let me know if this is the correct approach or I am still missing on something?
I woudn't call it "correct"...
Like @SGaist said, why do you think you need a thread? To emit a signal?! -
@shreya_agrawal is this the real code of your application ? Because using a thread to just trigger a GUI update is more than overkill.
@SGaist
Thank you for your response !
I realized that using threads won't be necessary in my use case, since I majorly have to update the GUI, which is recommended to be done by the main thread itself. So, now I am directly calling the cleaning function. Thank you for your time though. -