Russian Qt Forum
Май 01, 2024, 01:01 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1]   Вниз
  Печать  
Автор Тема: И снова "Cannot create children for a parent that is in a different thread."!  (Прочитано 7332 раз)
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
Записан
LisandreL
Птица говорун
*****
Offline Offline

Сообщений: 984


Надо улыбаться


Просмотр профиля
« Ответ #1 : Март 17, 2012, 13:51 »

Угадайте с 2 раз: в каком потоке выполнится вызванная напрямую из гуёвого потока функция doWork1()?
Правильно, из гуёвого.
Там же вы создаёте manager = new QNetworkAccessManager();, а он, очевидно, на работу из разных потоков не приспособлено.
Записан
Странник
Гость
« Ответ #2 : Март 17, 2012, 13:56 »

объявите doWork1 как слот и вызывайте его через очередь - по сигналу или с помощью QMetaObject::invokeMethod, например.
Записан
vbi
Гость
« Ответ #3 : Март 17, 2012, 14:06 »

Блиин, ну я дебил!!
Нужно ведь так:
Цитировать
   
    connect(thread,SIGNAL(started()),work,SLOT(doWork1()));
    thread->start();

А меня вот так вот, да еще девушка. Стыдно!!!
Записан
LisandreL
Птица говорун
*****
Offline Offline

Сообщений: 984


Надо улыбаться


Просмотр профиля
« Ответ #4 : Март 17, 2012, 22:51 »

да еще девушка
Непонимающий
Записан
Bepec
Гость
« Ответ #5 : Март 19, 2012, 09:03 »

Стыдно Веселый  Строит глазки
Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.052 секунд. Запросов: 22.