QT: manage the reply from a QNetworkReply

543 Views Asked by At

I'm new in QT development and I've to make a non-gui application that reads a token from a POST request and then launches some json requests using that token. My problem is what to do when the finished signal is launched. I've tried to pass the reply.readAll() to a QByteArray parameter of the object, but when I do this the value is always empty (""). My code was done based on this.

.h

#ifndef DOWNLOADER_H
#define DOWNLOADER_H

#include <QObject>
#include <QNetworkAccessManager>

class QNetworkReply;

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

    void test();
    bool finished = false;
    QByteArray data;

public slots:
    void handleReply(QNetworkReply* reply);

protected:
    QNetworkAccessManager m_manager;
};

#endif // DOWNLOADER_H

.cpp

#include "downloader.h"
#include <QNetworkRequest>
#include <QNetworkReply>
#include <QUrl>
#include <QVariant>
#include <QDebug>


Downloader::Downloader(QObject *parent) :
    QObject(parent)
{
    connect(&m_manager, SIGNAL(finished(QNetworkReply*)), SLOT(handleReply(QNetworkReply*)));
}

void Downloader::test() {
    QNetworkRequest request;
    QUrl url("http://192.168.25.25:8080/path/to/token");

    QUrl postData;
    postData.addQueryItem("client_id", "foo");
    postData.addQueryItem("username", "bar");
    postData.addQueryItem("password", "12345");
    postData.addQueryItem("grant_type", "password");

    request.setUrl(url);
    request.setHeader(QNetworkRequest::ContentTypeHeader,"application/x-www-form-urlencoded");

    QNetworkReply* rep = m_manager.post(request,postData.encodedQuery());

    rep->setProperty("url", QVariant(url));
    qDebug() << "Post " << rep << rep->url();

}

void Downloader::handleReply(QNetworkReply *reply) {
    qDebug() << "Handle" << reply << reply->url();
    qDebug() << "Dynamic property" << reply->property("url").isValid() << reply->property("url");
    qDebug() << "ReadAll " << reply->readAll();
    finished = true;
    data =reply->readAll();
    reply->deleteLater();
}

In main, the call is:

Downloader down;
    down.test();

    while (!down.finished)
    {
        usleep(3*1000*1100);//3,3s
        cout << "no finalizado";
    }

What I'm trying to do is to use the reply to fill a parameter and use this parameter from the main, when the finished bool is true. I know it's not correct, but I don't know how to manage the asynchronous nature of the request. What I need it's some guide to understand what I'm doing, since I've been searching in qt page, stackoverflow and others without success. Thanks in advance.

Update: my main function

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);
    Downloader down;
    down.test();
    return a.exec();
}
1

There are 1 best solutions below

0
wthung On

In class Downloader, declare a signal to emit the data to a slot of another QObject derived class. For example, in Downloader::handleReply you call emit dataReady(data). In the main function add below code:

Downloader down;
JsonSender obj;
connect(&down, &Downloader::dataReady, &obj, &JsonSender::dataReady);
down.test();
return a.exec();

In the slot dataReady of class JsonSender you can parse the token and send the request.