QT: управлять ответом от QNetworkReply - PullRequest
0 голосов
/ 18 июня 2020

Я новичок в разработке QT, и мне нужно создать приложение, отличное от gui, которое считывает токен из POST request, а затем запускает некоторые json requests с использованием этого токена. Моя проблема в том, что делать при запуске finished signal. Я пытался передать reply.readAll() параметру QByteArray объекта, но когда я делаю это, значение всегда пустое (""). Мой код был создан на основе 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();
}

В основном вызов :

Downloader down;
    down.test();

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

Я пытаюсь использовать reply для заполнения параметра и использовать этот параметр из main, когда finished bool равно true. Я знаю, что это неправильно, но я не знаю, как управлять асинхронным характером запроса. Мне нужно какое-то руководство, чтобы понять, что я делаю, так как я безуспешно искал на странице qt, stackoverflow и других. Заранее спасибо.

Обновление : моя основная функция

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

1 Ответ

0 голосов
/ 19 июня 2020

В классе Downloader объявить сигнал для передачи data в слот другого производного класса QObject. Например, набрав Downloader::handleReply, вы набираете emit dataReady(data). В основной функции добавьте ниже код:

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

В слоте dataReady класса JsonSender вы можете проанализировать токен и отправить запрос.

...