QT C ++ - нужна помощь QNetworkAccessManager!Классовая проблема - PullRequest
1 голос
/ 25 августа 2011

Я пытаюсь загрузить страницу с сервера в свою программу QT, но я искал способы сделать это, и они не очень много работают. Я не специалист по QT / C ++, так что будьте добры :)

Хорошо .. Пока я прихожу с этим кодом:

[СТАРЫЙ КОД] - проверьте обновленный код ниже!

http.cpp

#include "http.h"

http::http(QObject *parent) :
    QObject(parent)
{

    qDebug() << "HTTP ST";

    http1 = new QHttp(this);
    connect(http1, SIGNAL(done(bool)), this, SLOT(httpdown())); // Correction 1.
    http1->setHost("localhost");
    http1->get("/test.php");

    qDebug() << "HTTP END";


}

void http::httpdown()
{

    qDebug() << "completed!";
    qDebug() << http1->readAll();


}

http.h

#ifndef HTTP_H
#define HTTP_H

#include <QtNetwork>
#include <QHttp>
#include <QDebug>
#include <QObject>

class http : public QObject
{
    Q_OBJECT
public:
    explicit http(QObject *parent = 0);

signals:

public slots:
    void httpdown();

private:
    QHttp *http1;

};

#endif // HTTP_H

Ну, проблема в том, что httpdown () никогда не вызывается, и я попробовал все, что я знаю :( Возможно, я делаю это неправильно.

Помощь будет высоко ценится. Спасибо.


ОБНОВЛЕНИЕ ВОПРОСА

У меня есть предложение alexisdm и для проверки QNetworkAccessManager. Итак, вот новый код, корректно работающий с main ().

Когда я запускаю его из другого класса, я никогда не получаю сигнал.

[НОВЫЙ КОД]

http2.cpp

#include "http2.h"

http2::http2(QObject *parent) :
    QObject(parent)
{
    m_manager = new QNetworkAccessManager(this);
    connect(m_manager,SIGNAL(finished(QNetworkReply*)),this,SLOT(httpdown(QNetworkReply*)));

    QNetworkRequest request;
    request.setUrl(QUrl("http://localhost/test.php"));
    request.setRawHeader("User-Agent", "MyOwnBrowser 1.0");

    m_manager->get(request);
}

void http2::httpdown(QNetworkReply* result)
{

       QByteArray data= result->readAll();
       QString str(data);

       qDebug() <<  str;

}

http2.h

#ifndef HTTP2_H
#define HTTP2_H

#include <QObject>
#include <QDebug>
#include <QtNetwork>
#include <QNetworkReply>

class http2 : public QObject
{
    Q_OBJECT
public:
    explicit http2(QObject *parent = 0);

signals:

public slots:
    void httpdown(QNetworkReply* result);
private:
    QNetworkAccessManager* m_manager;

};

#endif // HTTP2_H

Теперь, если я позвоню прямо в main.cpp, вот так:

main.cpp

#include <QtCore/QCoreApplication>
#include "tcpserver.h"
#include "http2.h"

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    http2 h; // --> Working!!

    tcpserver mServer;

    return a.exec();
}

Работает нормально. Однако, если я вызову его внутри класса tcpserver, вот так:

tcpserver.cpp

#include "tcpserver.h"
#include "protocol.h"
#include "http2.h"

QTextStream in(stdin);

tcpserver::tcpserver(QObject *parent) :
    QObject(parent)
{
    server = new QTcpServer(this);

    [ ... Other Server Stuff ... ]

    // http2 h; // --> OLD CODE - Not Working :(

    http2 *h = new http2(this); // **--> NEW CODE working provided by alexisdm**

}

Сигнал никогда не происходит ... Что не так? Я здесь новенький! : P

Так или иначе, alexisdm сказал : «Возможно, объект http уничтожается до того, как сигнал может быть передан (например, если он был размещен в стеке)» - Решение принято, код ниже исправлен Прочитайте это: QT C ++ - нужна помощь QNetworkAccessManager! Задача класса (ссылка на ответ)

Что я должен сделать, чтобы избежать этого?

Спасибо! ;)

Ответы [ 2 ]

1 голос
/ 25 августа 2011

Ваш http или http2 объект уничтожается в конце конструктора, поскольку он размещен локально.

Вы должны, по крайней мере, выделить его динамически:

http2 *h = new http2(this);

Если вы хотите использовать его повторно, вы также можете объявить его как член tcpserver вместо использования локальной переменной.Если нет, вы должны как-то уничтожить его, когда он больше не нужен.


Редактировать

  • Если уничтожение выполняется в течениеВ слоте и / или в ответ на сигнал от h вы должны использовать QObject::deleteLater, а не немедленное удаление, потому что на объект все еще можно ссылаться где-то во время передачи сигнала.
    Так что либо deleteLater(); в httpdown() или h->deleteLater(); в tcpserver слоте.

  • Чтобы узнать, есть ли у вас ответ или ошибка, вы можете использовать этот код и отправьте либо данные, либо ошибку в ваш класс tcpserver с пользовательскими сигналами и слотами.

1 голос
/ 25 августа 2011

Строка:

SIGNAL(bool)

действительно не выглядит правильно;Вы имели в виду

SIGNAL(done(bool))

?

В режиме отладки должен быть какой-то отладочный вывод о том, что он не может подключить сигналы.

...