Nve
Nve

Reputation: 21

When trying to get a webpage using Qt QNetworkAccessManager, It always returns ""

I'm trying to get a web page using Qt and print it on the screen.The problem is it always prints "". It won't make it to the done SLOT. I don't know if there's something wrong with the connect(). The code gets compiled with no errors. Trying not to use event loops yet.

Here's the code:

net.h

#ifndef NET_H
#define NET_H

#include <QObject>
#include <QtNetwork>
#include <QString>
#include <QDebug>

class net : public QObject
{
    Q_OBJECT
public:
    explicit net(QObject *parent = 0);
    void get_site(QString url);
    QString data;

signals:

public slots:
    void err(QNetworkReply *);
    void done(QNetworkReply *);

private:

};

#endif // NET_H

net.cpp:

#include "net.h"

net::net(QObject *parent) :
    QObject(parent)
{
}

void net::get_site(QString url) {
    QNetworkAccessManager man;
    QNetworkRequest request;

    request.setUrl (QUrl(url));

    connect (&man , SIGNAL(finished(QNetworkReply*)) ,this, SLOT(done(QNetworkReply*)));
    connect (&man , SIGNAL(finished(QNetworkReply*)) ,this, SLOT(err(QNetworkReply *)));

    man.get (QNetworkRequest(QUrl(url)));
}

void net::done(QNetworkReply * reply) {
    data = QString(reply->readAll ());
}

void net::err(QNetworkReply * reply) {
    data = QString(reply->errorString ());
}

And main.cpp:

#include <QCoreApplication>
#include "net.h"


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

    net netobj;
    netobj.get_site("http://stackoverflow.com");
    qDebug() << netobj.data;
    return a.exec();
}

Upvotes: 2

Views: 947

Answers (2)

Nejat
Nejat

Reputation: 32645

There are some major problems in your code. First you should have the QNetworkAccessManager as a class member in .h file :

class net : public QObject
{
    ...
private:
    QNetworkAccessManager nam;
};

Also you should not connect the finished signal to two different slots. Your get_site function should be like :

void net::get_site(QString url) {

    QNetworkRequest request;
    request.setUrl (QUrl(url));

    connect (&man , SIGNAL(finished(QNetworkReply*)) ,this, SLOT(done(QNetworkReply*)));

    man.get (QNetworkRequest(QUrl(url)));
}

And you should manage the returned reply in the following way :

void net::done(QNetworkReply * reply) {


    if (reply->error() == QNetworkReply::NoError)
    {
       data = QString(reply->readAll ());
    }
    else
    {
       data = QString(reply->errorString ());
    }
}

Upvotes: 1

orfdorf
orfdorf

Reputation: 1010

Your QNetworkAccessManager instance goes out of scope at the end of your get_site function. According to Qt docs, one QNetworkAccessManager should be enough for the whole Qt application. Your object should persist outside the scope of that function, since it's likely the response will take longer to receive than it will take for that function to end. Make the QNetworkAccessManager a member of your net class, instead of an automatic variable local to get_site.

Note that you also need to manage the lifetime of the QNetworkReply object, not by using delete, but by using deleteLater() or else you might leak memory.

Upvotes: 0

Related Questions