Russian Qt Forum

Qt => Многопоточное программирование, процессы => Тема начата: vbi от Март 17, 2012, 13:10



Название: И снова "Cannot create children for a parent that is in a different thread."!
Отправлено: vbi от Март 17, 2012, 13:10
Я пытаюсь разобратся с агрегатным использованием мультипоточности, и уже совсем запутался какой объект в каком потоке находится.

Вот код при нажатии кнопки:

Код:
void MainWindow::on_pushButton_clicked()
{
    QThread* thread = new QThread();
    thread->start();
    Worker* work = new Worker; // наследован от QObject
    work->moveToThread(thread);
    work->doWork1();
}

Вот класс Worker

H:
Код:
#ifndef WORKER_H
#define WORKER_H

#include <QObject>
#include <QThread>
#include <QtNetwork/QNetworkAccessManager>
#include <QUrl>
#include <QtNetwork/QNetworkRequest>
#include <QtNetwork/QNetworkReply>
#include <QDebug>

class Worker : public QObject
{
    Q_OBJECT
public:
    explicit Worker(QObject *parent = 0);
    void doWork1();
    QNetworkAccessManager* manager;
signals:
   
public slots:
    void doWork2(QNetworkReply* reply);
    void doWork3(QNetworkReply* reply);
};

#endif // WORKER_H

CPP:

Код:
#include "worker.h"

Worker::Worker(QObject *parent) :
    QObject(parent)
{
}

void Worker::doWork1()
{
    qDebug()<<"Start work 1";
    manager = new QNetworkAccessManager();
    connect(manager,SIGNAL(finished(QNetworkReply*)),this,SLOT(doWork2(QNetworkReply*)));
    manager->get(QNetworkRequest(QUrl("http://ya.ru")));
    qDebug()<<"End work 1";
}

void Worker::doWork2(QNetworkReply *reply)
{
    qDebug()<<"Start work 2";
    QByteArray b = reply->readAll();
    disconnect(manager,SIGNAL(finished(QNetworkReply*)),this,SLOT(doWork2(QNetworkReply*)));
    connect(manager,SIGNAL(finished(QNetworkReply*)),this,SLOT(doWork3(QNetworkReply*)));
    manager->get(QNetworkRequest(QUrl("http://mail.ru")));
    qDebug()<<"End work 2";
}

void Worker::doWork3(QNetworkReply *reply)
{
    qDebug()<<"Start work 3";
    QByteArray b = reply->readAll();
    qDebug()<<"End work 3";
}


Когда я нажимаю в окне кнопку - создается новый поток, создается объект класса Worker (в его конструкторе ничего не создается), стартует поток, потом Worker перемещается в созданный поток и запускается процедура "Work1".

В этой процедуре создается QNetworkAccessManager и передает GET запрос куда-то там.

Возвращается QNetworkReply в процедуру "Work2", в которой этот менеджер делает новый запрос GET.

Вот почемуто, когда менеджер делает новый запрос GET в процедуре  "Work2" - лезут сообщения "Cannot create children for a parent that is in a different thread."

Не могу понять почему, ведь и QNetworkAccessManager был создан в потоке. Получается что QNetworkReply возвращается в другом потоке? Почему? Как с этим боротся?

Исходники прилагаются: http://www.fayloobmennik.net/1672364 (http://www.fayloobmennik.net/1672364)


Название: Re: И снова "Cannot create children for a parent that is in a different thread."!
Отправлено: LisandreL от Март 17, 2012, 13:51
Угадайте с 2 раз: в каком потоке выполнится вызванная напрямую из гуёвого потока функция doWork1()?
Правильно, из гуёвого.
Там же вы создаёте manager = new QNetworkAccessManager();, а он, очевидно, на работу из разных потоков не приспособлено.


Название: Re: И снова "Cannot create children for a parent that is in a different thread."!
Отправлено: Странник от Март 17, 2012, 13:56
объявите doWork1 как слот и вызывайте его через очередь - по сигналу или с помощью QMetaObject::invokeMethod, например.


Название: Re: И снова "Cannot create children for a parent that is in a different thread."!
Отправлено: vbi от Март 17, 2012, 14:06
Блиин, ну я дебил!!
Нужно ведь так:
Цитировать
   
    connect(thread,SIGNAL(started()),work,SLOT(doWork1()));
    thread->start();

А меня вот так вот, да еще девушка. Стыдно!!!


Название: Re: И снова "Cannot create children for a parent that is in a different thread."!
Отправлено: LisandreL от Март 17, 2012, 22:51
да еще девушка
???


Название: Re: И снова "Cannot create children for a parent that is in a different thread."!
Отправлено: Bepec от Март 19, 2012, 09:03
Стыдно :D  ::)