Russian Qt Forum

Qt => Работа с сетью => Тема начата: jjoss от Январь 13, 2010, 16:23



Название: QT 4.6.0 QNetworkAccessManager - сигнал finished()
Отправлено: jjoss от Январь 13, 2010, 16:23
Суть проблемы в следующем.
Есть класс "A" - наследник QObject. В качестве private-члена у него есть
Код:
private:
....
QNetworkAccessManager manager;
...

В конструкторе класса соединятся сигнал finished(QNetworkReply *) со слотом для обработки следующим образом
Код:
...
connect(&manager, SIGNAL(finished(QNetworkReply *)),
          this, SLOT(replyIsRecieved(QNetworkReply *)));
...
Далее. Есть класс "B", у которого в качестве private-члена есть указатель на объект класса "A", который соответственно инициализируется в конструкторе. Методы класса "B" инициализируют необходимые параметры класса "A", и последний выполняет
Код:
manager.get(QNetworkRequest(url));
Заковыка в том, что сигнал finished(QNetworkReply *) не отлавливается, т.е. банально при трассировке не попадаю в replyIsRecieved(QNetworkReply *). В чём может быть проблема?


Название: Re: QT 4.6.0 QNetworkAccessManager - сигнал finished()
Отправлено: ecspertiza от Январь 13, 2010, 16:49
Накидай минимальный компилируемый пример


Название: Re: QT 4.6.0 QNetworkAccessManager - сигнал finished()
Отправлено: jjoss от Январь 13, 2010, 17:20
Накидай минимальный компилируемый пример

Прошу извинить за отсутствие всякого стиля :) - только в качестве примера.
Модуль A (aa.h)
Код:
#ifndef AA_H
#define AA_H

#include <QObject>
#include <QNetworkAccessManager>
#include <QNetworkRequest>
#include <QDebug>
class A : public QObject
{
  Q_OBJECT
  QNetworkAccessManager manager;
public:
    A(QObject *parent = 0);
    ~A();
    void doRequest();
private slots:
  void replyIsRecieved(QNetworkReply* reply);   
};

#endif // AA_H
a.cpp
Код:
#include "aa.h"

A::A(QObject *parent)
  : QObject(parent)
{
  connect(&manager, SIGNAL(finished(QNetworkReply *)),
           SLOT(replyIsRecieved(QNetworkReply *)));
}

A::~A()
{

}
void A::doRequest()
{
  QNetworkReply *currentReply = manager.get(QNetworkRequest(QUrl("www.ya.ru")));
}

void A::replyIsRecieved(QNetworkReply* reply)
{
 qDebug() << "OK";
}
Модуль B
b.h
Код:
#ifndef B_H
#define B_H

#include <QDialog>
#include <aa.h>
class B : public QObject
{
  Q_OBJECT

public:
    B(QObject *parent = 0, A *man = 0);
    ~B();
    void makeRequest();
private:
  A *requestManager; 
};

#endif // B_H
b.cpp
Код:
#include "b.h"

B::B(QObject *parent, A *man)
  : QObject(parent)
{
  requestManager = man;
}

B::~B()
{

}

void B::makeRequest()
{
  requestManager->doRequest();
}
main.cpp
Код:
#include <QtGui/QApplication>
#include <QNetworkAccessManager>
#include <QDialog>
#include <aa.h>
#include <b.h>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    A reqMan;
    B wnd(0, &reqMan);
    wnd.makeRequest();
    return a.exec();
}


Название: Re: QT 4.6.0 QNetworkAccessManager - сигнал finished()
Отправлено: zenden от Январь 13, 2010, 17:36
У меня печатает "OK"

Возникло подозрение, а не уничтожается ли экземпляр одного из классов (A, B) до того, как этот сигнал будет выслан. Как вижу, здесь вы используете их в стеке, возможно и в вашей программе так?


Название: Re: QT 4.6.0 QNetworkAccessManager - сигнал finished()
Отправлено: ecspertiza от Январь 13, 2010, 17:38
Хм... собрал твой пример ,все работает хорошо На экран выводится "Ok"  что говорит о том что слот выполнен.

На всякий случай прилагаю архив.


Название: Re: QT 4.6.0 QNetworkAccessManager - сигнал finished()
Отправлено: jjoss от Январь 13, 2010, 17:43
Странно... Ну, все равно, спасибо!
Полезу в код. Дело в том, что пример и у меня сработал корректно. А вот в проекте - нет. Но там есть одно НО!
Реквест выполняется модальной формой.
Так вот, если её не заставлять ждать результат - то всё срабатывает, а если заставлять - типа
while(proccessing)
{
  //дисэйблить форму
}
то нет.... Есть подозрение, что когда дисэйблю - цикл обработки не работает, хотя не уверен...


Название: Re: QT 4.6.0 QNetworkAccessManager - сигнал finished()
Отправлено: ecspertiza от Январь 13, 2010, 17:45
Не знаю может я не так понял, но попробуй форму задизейблить так
qApp->processEvents(QEventLoop::ExcludeUserInputEvents);


Название: Re: QT 4.6.0 QNetworkAccessManager - сигнал finished()
Отправлено: jjoss от Январь 13, 2010, 17:50
Не знаю может я не так понял, но попробуй форму задизейблить так
qApp->processEvents(QEventLoop::ExcludeUserInputEvents);

Йо!!! Спасибо огромное!!!
Все корректно теперь.


Название: Re: QT 4.6.0 QNetworkAccessManager - сигнал finished()
Отправлено: jjoss от Январь 13, 2010, 17:59
Ещё раз, спасибо!!!
Тему можно закрывать.