Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

QObject: Cannot create children for a parent that is in a different thread

Tags:

c++

qt

I am using Qt 4.6.0 (32 bit) under Windows 7 Ultimate. Consider the following QThread:

Interface

class ResultThread : public QThread { Q_OBJECT      QString _post_data;     QNetworkAccessManager _net_acc_mgr;  signals:     void onFinished(QNetworkReply* net_reply);  private slots:     void onReplyFinished(QNetworkReply* net_reply);  public:     ResultThread();      void run();     void setPostData(const QString& post_data); }; 

Implementation

ResultThread::ResultThread() : _net_acc_mgr(this) {     connect(&_net_acc_mgr, SIGNAL(finished(QNetworkReply*)),             this, SLOT(onReplyFinished(QNetworkReply*))); }  void ResultThread::onReplyFinished(QNetworkReply* net_reply) {     emit onFinished(net_reply); }  void ResultThread::setPostData(const QString& post_data) {     _post_data = post_data; }  void ResultThread::run() {     _net_acc_mgr.post(QNetworkRequest(QUrl("http://[omitted]")),                       QByteArray(_post_data.toStdString().c_str())); } 

Whenever _net_acc_mgr.post() is executed in ResultThread::run(), I got the following Application Output in Qt Creator:

QObject: Cannot create children for a parent that is in a different thread.

(Parent is QNetworkAccessManager(0x22fe58), parent's thread is QThread(0x9284190), current thread is ResultThread(0x22fe48)

What does this mean? How to solve it?

like image 818
Donotalo Avatar asked Jul 16 '10 19:07

Donotalo


1 Answers

The run() member function is executed in a different thread, rather than the thread where QNetworkRequestManager object was created.

This kind of different-thread problems happen all the time with Qt when you use multiple threads. The canonical way to solve this problem is to use signals and slots.

Create a slot in the object where QNetworkRequestManager belongs to, create a signal in ResultThread and connect both of the somewhere, the constructor of ResultThread would be a good place.

The code which is currently in ResultThread::run() goes to the new slot, and is replaced by a emit(yourSignal()). If necessary send a pointer to your ResultThread as a parameter with your emit function to gain access to member functions/variables.

like image 92
Gunther Piez Avatar answered Sep 19 '22 21:09

Gunther Piez