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

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

Страниц: [1]   Вниз
  Печать  
Автор Тема: QNetworkAccessManager и QThread  (Прочитано 5016 раз)
momo11
Гость
« : Январь 13, 2014, 10:50 »

Сделал класс который в несколько потоков запрашивает страницу и результат выводит в qDebug.
хэдер:
Код:
#ifndef CHECK_H
#define CHECK_H
#include <QMainWindow>
#include <QDebug>
#include <QMessageBox>
#include <QtNetwork/QNetworkAccessManager>
#include <QUrl>
#include <QtNetwork/QNetworkRequest>
#include <QtNetwork/QNetworkReply>
#include <QThread>

class Check : public QThread
{
public:
    Check(QObject *parent = 0) : QThread(parent) {}
    virtual void run();

private slots:
        void end(QNetworkReply*);

private:
    QNetworkAccessManager *Mgr;

};

#endif // CHECK_H

Сам файл
Код:
#include "check.h"

Check::run()
{
    qDebug()<<"runn";
    QNetworkAccessManager *Mgr = new QNetworkAccessManager(this);
    connect(manager, SIGNAL(finished(QNetworkReply*)), this, SLOT(end(QNetworkReply*)));
    manager->get(QNetworkRequest(QUrl("http://site.com")));
}

Check::end(QNetworkReply* reply)
{
    qDebug()<<reply->readAll();
}

Ошибки:
Код:
D:\QT\Tools\QtCreator\bin\myprog\check.cpp:3: ошибка: ISO C++ forbids declaration of 'run' with no type [-fpermissive]
 Check::run()
            D:\QT\Tools\QtCreator\bin\myprog\check.cpp:3: ошибка: prototype for 'int Check::run()' does not match any in class 'Check'
 Check::run()
 ^
D:\QT\Tools\QtCreator\bin\myprog\check.cpp:1: In file included from ..\myprog\check.cpp:1:0:
D:\QT\Tools\QtCreator\bin\myprog\check.h:16: ошибка: candidate is: virtual void Check::run()
     virtual void run();
                  ^
D:\QT\Tools\QtCreator\bin\myprog\check.cpp:11: ошибка: ISO C++ forbids declaration of 'end' with no type [-fpermissive]
 Check::end(QNetworkReply* reply)
                                ^
D:\QT\Tools\QtCreator\bin\myprog\check.cpp:11: ошибка: prototype for 'int Check::end(QNetworkReply*)' does not match any in class 'Check'
 Check::end(QNetworkReply* reply)
 ^
D:\QT\Tools\QtCreator\bin\myprog\check.cpp:1: In file included from ..\myprog\check.cpp:1:0:
D:\QT\Tools\QtCreator\bin\myprog\check.h:19: ошибка: candidate is: void Check::end(QNetworkReply*)
         void end(QNetworkReply*);
              ^
« Последнее редактирование: Январь 13, 2014, 10:52 от momo11 » Записан
Serr500
Гость
« Ответ #1 : Январь 13, 2014, 11:16 »

void перед run и end в реализации кто будет указывать? Если нет ничего, предполагается int и сейчас так вообще не принято и большинство компиляторов по умолчанию это считает ошибкой.
Записан
momo11
Гость
« Ответ #2 : Январь 13, 2014, 12:41 »

Точно, исправил, но теперь программа крашится при запуске потока.
Запускаю так:
Код:
 Check asd;
    asd.start();

и ошибки в выводе приложения:
Код:
QThread: Destroyed while thread is still running
QMutex: destroying locked mutex
Программа неожиданно завершилась.
Записан
Serr500
Гость
« Ответ #3 : Январь 13, 2014, 12:59 »

Похоже, документацию по QThread Вы вообще не читали.

1) Как только завершился run, ваш потомок QThread остановит работу и ничего больше выполняться там не будет.
2) Переменная типа Check у Вас где-то в стеке функции и разрушается при выходе из этой функции.
3) Зачем Вам поток? QNAM сам по себе асинхронный.
Записан
momo11
Гость
« Ответ #4 : Январь 13, 2014, 13:26 »

значит run завершается, а из run'a у меня идет сигнал  connect(Mgr, SIGNAL(finished(QNetworkReply*)), this, SLOT(end(QNetworkReply*))); , как сделать чтобы run не завершался а ждал пока сигнал на сработает?
может быть создать бесконечный цикл который будет проверять записался ли в переменную исходный код страницы, если нет то ожидать и снова проверять
Записан
momo11
Гость
« Ответ #5 : Январь 13, 2014, 13:32 »

или может у thread'ов есть какое нибудь свойство, которое не дает завершить поток пока все сигналы не сработали
Записан
Serr500
Гость
« Ответ #6 : Январь 13, 2014, 15:05 »

значит run завершается, а из run'a у меня идет сигнал  connect(Mgr, SIGNAL(finished(QNetworkReply*)), this, SLOT(end(QNetworkReply*)));
Сигнал идёт не из run'а. Сигнал идёт от QNAM, а в run он просто соединяется со слотом. Сигнал почти наверняка пойдёт уже после выхода из run.

как сделать чтобы run не завершался а ждал пока сигнал на сработает?
Например, в конце run вызвать exec. Тогда event loop потока будет крутиться, пока ему не вызовут quit (или terminate).

может быть создать бесконечный цикл который будет проверять записался ли в переменную исходный код страницы, если нет то ожидать и снова проверять
Это решение уровня DOS 5.0.  Смеющийся

или может у thread'ов есть какое нибудь свойство, которое не дает завершить поток пока все сигналы не сработали
Нет.
Записан
momo11
Гость
« Ответ #7 : Январь 13, 2014, 16:07 »

уже прогресс небольшой, вот методы класса который выполняется в потоке
Код:
void Check::run()
{
    qDebug()<<"runn";
    QNetworkAccessManager *Mgr = new QNetworkAccessManager(this);
    connect(Mgr, SIGNAL(finished(QNetworkReply*)), this, SLOT(end(QNetworkReply*)));
    Mgr->get(QNetworkRequest(QUrl("http://wapos.ru")));
    exec();
}

void Check::end(QNetworkReply* reply)
{
    qDebug()<<reply->readAll();
    quit();
}
runn выводится, а вот далее идут ошибки
Код:
QObject: Cannot create children for a parent that is in a different thread.
(Parent is QThread(0x22fe40), parent's thread is QThread(0x12bdcc0), current thread is QThread(0x22fe40)
QObject::connect: No such slot QThread::end(QNetworkReply*)
QThread: Destroyed while thread is still running

вызываю так
Код:
    asd.start();
asd создана как глобальная переменная, чтобы не дохла после нажатия кнопки
Записан
Serr500
Гость
« Ответ #8 : Январь 13, 2014, 16:37 »

Код:
QNetworkAccessManager *Mgr = new QNetworkAccessManager();
Mgr->moveToThread(this);
Записан
momo11
Гость
« Ответ #9 : Январь 13, 2014, 16:59 »

может я чего то не догоняю, но помоему ничего не изменилось, те же ошибки
Записан
Serr500
Гость
« Ответ #10 : Январь 13, 2014, 20:09 »

Выложите весь проект, будем посмотреть, по кускам непонятно.
Записан
Old
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4350



Просмотр профиля
« Ответ #11 : Январь 13, 2014, 20:22 »

может я чего то не догоняю, но помоему ничего не изменилось, те же ошибки
Самое простое не передавать parent в конструктор QNetworkAccessManager (убрать this), но нужно будет не забывать самому его удалять.
Лучше сделать так:
Код
C++ (Qt)
void Check::run()
{
   qDebug()<<"runn";
   QNetworkAccessManager Mgr;
   connect( &Mgr, SIGNAL(finished(QNetworkReply*)), this, SLOT(end(QNetworkReply*)));
   Mgr.get(QNetworkRequest(QUrl("http://wapos.ru")));
   exec();
}
 
« Последнее редактирование: Январь 13, 2014, 20:46 от Old » Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


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