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

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

Страниц: [1]   Вниз
  Печать  
Автор Тема: Класс с слотом, наследованный от QHttp  (Прочитано 4366 раз)
Sm[SteeL]
Гость
« : Сентябрь 12, 2009, 21:47 »

Вначале опишу, что у меня есть:

Обычное окошко, в котором есть ListView (тут никаких проблем нету):
main.cpp:
Код:
#include <QtGui/QApplication>
#include <QtGui/QMainWindow>
#include <QtGui/QFrame>
#include <QtGui/QListView>
#include <QtGui/QStringListModel>
#include <QStringList>
#include "network.h"

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    QMainWindow * main = new QMainWindow();
    QFrame * mainframe = new QFrame();
    mainframe->setFrameShape(QFrame::Box);
    mainframe->setParent(main);
    mainframe->show();
    QStringListModel * mdl = new QStringListModel();
    QStringList * slist = new QStringList();
    network * nw = new network();
    nw->getserveraddr(&*slist);
    mdl->setStringList(*slist);
    QListView * list = new QListView();
    list->setModel(mdl);
    list->setGeometry(10,10,620,460);
    list->setParent(mainframe);
    list->show();
    list->setViewMode(QListView::ListMode);
    main->setFixedSize(640, 480);
    main->setWindowTitle("IM");
    main->setCentralWidget(mainframe);
    main->show();
    return a.exec();
}

Есть класс network, который наследует от QHttp и имеет свой слот:
network.h:
Код:
#ifndef NETWORK_H
#define NETWORK_H
#include <QtNetwork/QHttp>
#include <QStringList>

using namespace std;

class network : public QHttp
{
    Q_OBJECT
public:
    network();
    void getserveraddr(QStringList *slist);

public slots:
   void returnserveraddr();

private:
    QStringList * rlist;
    QString defserver_addr;
    qint16 defserer_port;
};

#endif // NETWORK_H

И network.cpp:
Код:
#include "network.h"

network::network()
{
    this->defserver_addr = "mrim.mail.ru";
    this->defserer_port = 2042;
}

void network::getserveraddr(QStringList *slist)
{
    this->rlist = &*slist;
    *(this->rlist) << "foo";
    this->connect(this, SIGNAL(done(bool)), this, SLOT(returnserveraddr()), Qt::AutoConnection);
    this->setHost(this->defserver_addr, this->defserer_port);
    this->get("/");
}

void network::returnserveraddr()
{
    qDebug() << this->readAll();
    *(this->rlist) << "bar";
}

В мэйне я передаю указатель на QStringList в метод класса, внутри этого метода я потоком записываю в него "foo", что замечательно отрабатывает.
В методе, который я вызвал (network::getserveraddr) я устанавливаю соединение с сервером и хочу по сигналу done(bool):
1) считать и вывести в дебаг всю инфу, полученную get'ом.
2) и просто пробую использовать тот же самый указатель, что и в getserveraddr.
Ни то, ни другое не отрабатывает (т.е. ошибок нет, но ничего в указателе не оказывается, а в дебаг выводится пустая строка).
В чем тут проблема(ы)?Улыбающийся
Заранее спасибо.
« Последнее редактирование: Сентябрь 13, 2009, 03:57 от Sm[SteeL] » Записан
Sm[SteeL]
Гость
« Ответ #1 : Сентябрь 12, 2009, 21:59 »

Почему не выводиться "bar" я понял. Это же слот, вызываемый сигналом, а я вывожу список до того, как сигнал вызывается.
Но вопрос про QHttp остается в силе.
Записан
Sm[SteeL]
Гость
« Ответ #2 : Сентябрь 13, 2009, 02:58 »

Изменил исходники следующим образом:
network.h:
Код:
#ifndef NETWORK_H
#define NETWORK_H
#include <QtNetwork>
#include <QStringList>
#include <QBuffer>

class Network : QObject
{
    Q_OBJECT
public:
    Network(QObject *parent=0);
    void getserveraddr(QStringList *slist);

public slots:
   void on_requestFinished(int requestId, bool error);
   void on_readyRead(QHttpResponseHeader responseHeader);
   void on_done(bool error);
   void on_requestStarted(int id);
   void on_stateChanged(int state);
   void on_responseHeaderReceived(QHttpResponseHeader responseHeader);
   void on_sslErrors(QList<QSslError> errors);
   void on_authenticationRequired(QString hostname, quint16 port, QAuthenticator * authenticator);

private:
    int getId;
    QHttp * http;
    QStringList * rlist;
    QString defserver_addr;
    qint16 defserer_port;
};

#endif // NETWORK_H
network.cpp:
Код:
#include "network.h"

Network::Network(QObject *parent) : QObject(parent)
{
    this->defserver_addr = "mrim.mail.ru";
    this->defserer_port = 2042;
    this->http = new QHttp();
}

void Network::getserveraddr(QStringList *slist)
{
    connect(this->http, SIGNAL(requestFinished(int, bool)), this, SLOT(on_requestFinished(int, bool)));
    connect(this->http, SIGNAL(readyRead(QHttpResponseHeader)), this, SLOT(on_readyRead(QHttpResponseHeader)));
    connect(this->http, SIGNAL(done(bool)), this, SLOT(on_done(bool)));
    connect(this->http, SIGNAL(requestStarted(int)), this, SLOT(on_requestStarted(int)));
    connect(this->http, SIGNAL(stateChanged(int)), this, SLOT(on_stateChanged(int)));
    connect(this->http, SIGNAL(responseHeaderReceived(QHttpResponseHeader)), this, SLOT(on_responseHeaderReceived(QHttpResponseHeader)));
    connect(this->http, SIGNAL(sslErrors(QList<QSslError>)), this, SLOT(on_sslErrors(QList<QSslError>)));
    connect(this->http, SIGNAL(authenticationRequired(QString,quint16,QAuthenticator*)), this, SLOT(on_authenticationRequired(QString,quint16,QAuthenticator*)));
    this->http->setHost(this->defserver_addr, QHttp::ConnectionModeHttp, this->defserer_port);
    this->getId = this->http->get("/");
    qDebug() << "Get id: " << this->getId;
}

void Network::on_requestFinished(int requestId, bool error)
{
    qDebug() << "Request " << requestId << " finished with error: " << error;
    if(requestId == this->getId)
        qDebug() << "Data: " << this->http->readAll();
}

void Network::on_readyRead(QHttpResponseHeader responseHeader)
{
    qDebug() << "Ready read";
    qDebug() << "Response status: " << responseHeader.statusCode();
}

void Network::on_done(bool error)
{
    qDebug() << "Done";
}

void Network::on_requestStarted(int id)
{
    qDebug() << "Request " << id << " started";
}

void Network::on_stateChanged(int state)
{
    switch(state)
    {
        case 0:
            qDebug() << "State changed to: Unconnected";
            return;
        case 1:
            qDebug() << "State changed to: HostLookup";
            return;
        case 2:
            qDebug() << "State changed to: Connecting";
            return;
        case 3:
            qDebug() << "State changed to: Sending";
            return;
        case 4:
            qDebug() << "State changed to: Reading";
            return;
        case 5:
            qDebug() << "State changed to: Connected";
            return;
        case 6:
            qDebug() << "State changed to: Closing";
            return;
    }
}

void Network::on_responseHeaderReceived(QHttpResponseHeader responseHeader)
{
    qDebug() << "Response header received";
    qDebug() << "Status code: " << responseHeader.statusCode();
}

void Network::on_sslErrors(QList<QSslError> errors)
{
    qDebug() << "SSL Errors occured";
}

void Network::on_authenticationRequired(QString hostname, quint16 port, QAuthenticator * authenticator)
{
    qDebug() << "Auth required";
}

Вывод получается такой:
Цитировать
Get id:  2
Request  1  started
Request  1  finished with error:  false
Request  2  started
State changed to: Connecting
State changed to: Sending
State changed to: Reading
State changed to: Closing
State changed to: Unconnected
Request  2  finished with error:  false
Data:  ""
Done
Если же брать данные с того же ya.ru, я получу:
Цитировать
Get id:  2
Request  1  started
Request  1  finished with error:  false
Request  2  started
State changed to: Connecting
State changed to: Sending
State changed to: Reading
Response header received
Status code:  200
Ready read
Response status:  200
Ready read
Response status:  200
State changed to: Connected
Request  2  finished with error:  false
Data:  "<!DOCTYPE HTML PUBL ... (весь html код) ... ipt>"
Done
Вопрос: как мне все-таки получить данные по запросу GET именно с mrim.mail.ru? О_о
« Последнее редактирование: Сентябрь 13, 2009, 03:41 от Sm[SteeL] » Записан
Sm[SteeL]
Гость
« Ответ #3 : Сентябрь 13, 2009, 15:09 »

В целом проблема решена. Просто тот сервер не возвращает нормальных заголовков. Реализовал через QTCPSocket.
Но теперь интересует следующее:
Я могу по сигналу readyread сокета прочитать данные вот так:
Код:
void TCPNetwork::on_readyread()
{
    qDebug() << "Ready to read";
    qDebug() << "Data: " << this->socket.readAll();
}
Но читать все данные будет неудобно, хотелось бы что-нибудь вроде:
Код:
void TCPNetwork::on_readyread()
{
    qDebug() << "Ready to read";
    QDataStream in(&(this->socket));
    in.setVersion(QDataStream::Qt_4_1);
    QString data;
    in >> data;
    qDebug() << "Data: " << data;
}
Но в переменной data ничего не оказывается... В чем тут проблема?
Записан
Sm[SteeL]
Гость
« Ответ #4 : Сентябрь 13, 2009, 18:51 »

В общем все сделал =))))
Записан
Karl-Philipp
Гость
« Ответ #5 : Сентябрь 13, 2009, 19:19 »

поделись решением Улыбающийся
Записан
Sm[SteeL]
Гость
« Ответ #6 : Сентябрь 13, 2009, 20:50 »

Ну там в итоге нужно было все равно рассматривать не QString, а RawData, да еще и не в сетевом формате, так что я просто использовал readAll().
Сейчас делаю, собственно, ф-цию создания пакета из RawData в QByteArray.
« Последнее редактирование: Сентябрь 14, 2009, 00:03 от Sm[SteeL] » Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


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