QObject: impossible de créer des enfants pour un parent se trouvant dans un thread différent

J’utilise Qt 4.6.0 (32 bits) sous Windows 7 Ultimate. Considérez le QThread suivant:

Interface

 class ResultThread : public QThread { Q_OBJECT QSsortingng _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 QSsortingng& post_data); }; 

la mise en oeuvre

 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 QSsortingng& post_data) { _post_data = post_data; } void ResultThread::run() { _net_acc_mgr.post(QNetworkRequest(QUrl("http://[omitted]")), QByteArray(_post_data.toStdSsortingng().c_str())); } 

Chaque fois que _net_acc_mgr.post() est exécuté dans ResultThread::run() , j’ai reçu la sortie d’application suivante dans Qt Creator:

QObject: impossible de créer des enfants pour un parent situé dans un thread différent.

(Parent est QNetworkAccessManager (0x22fe58), le thread du parent est QThread (0x9284190), le thread en cours est ResultThread (0x22fe48)

Qu’est-ce que ça veut dire? Comment le résoudre?

La fonction membre run () est exécutée dans un thread différent, plutôt que le thread où l’object QNetworkRequestManager été créé.

Ce type de problème de thread différent se produit tout le temps avec Qt lorsque vous utilisez plusieurs threads. La manière canonique de résoudre ce problème consiste à utiliser des signaux et des slots .

Créez un emplacement dans l’object QNetworkRequestManager appartient QNetworkRequestManager , créez un signal dans ResultThread et connectez-vous quelque part, le constructeur de ResultThread serait un bon endroit.

Le code qui se trouve actuellement dans ResultThread :: run () va dans le nouvel emplacement et est remplacé par un emit(yourSignal()) . Si nécessaire, envoyez un pointeur sur votre ResultThread en tant que paramètre avec votre fonction emit pour accéder aux fonctions / variables membres.