Question

I'm trying to download a page from a server to my QT program, but I've been searching ways to do it and they don't really work a lot. I'm not an expert in QT/C++, so be kind :)

Well.. So far I come with this code:

[OLD CODE] - Check the updated code bellow!

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

Well the problem is that httpdown() is never called, and I've tried anything I know :( Probably I'm not doing this correctly.

Help will be much appreciated. Thanks.


QUESTION UPDATE

I've ear the suggestion of alexisdm and to check QNetworkAccessManager. So here it is new code working on the main() correctly.

When I run it from another class I never get the signal.

[NEW CODE]

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

Now if I call it directly under main.cpp like this:

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();
}

It works fine. However if I call it inside the tcpserver class like this:

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**

}

The signal never happens... What's wrong? I'm new here! :P

Anyway, alexisdm said: "Maybe the http object gets destroyed before the signal can be emitted (if it was allocated on the stack for example)" - Solution accepted, code bellow corrected Read this: QT C++ - QNetworkAccessManager help needed! Class problem (link to answer)

What should I do to avoid that?

Thanks! ;)

Was it helpful?

Solution

Your http or http2 object is destroyed at the end of the constructor, because it is allocated locally.

You should at least allocate it dynamically:

http2 *h = new http2(this);

If you want to reuse it, you can also declare it as a member of tcpserver, instead of using a local variable. If not, you should destroy it somehow when it is not needed anymore.


Edit

  • If the destruction is done within the slot and/or in response to a signal from h, you should use QObject::deleteLater rather than an immediate delete, because the object might still be referenced somewhere at the time the signal is emitted.
    So either deleteLater(); in httpdown() or h->deleteLater(); in a tcpserver slot.

  • To know if you have an answer or an error you could use that code and forward either the data or the error to your tcpserver class with custom signal(s) and slot(s).

OTHER TIPS

The line:

SIGNAL(bool)

really doesn't look right; did you mean

SIGNAL(done(bool))

?

In debug mode, there should be some debug output saying that it could not connect the signals.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top