Получение JSON используя QNetworkAccessManager \ QFuture \ QFutureWatcher :: Cетевой уголок Majestio

Получение JSON используя QNetworkAccessManager \ QFuture \ QFutureWatcher


Так сказать мой набросок для Stackoverflow:

AsyncReply.pro

QT -= gui
QT += core network concurrent
 
CONFIG += c++11 console
CONFIG -= app_bundle
DEFINES += QT_DEPRECATED_WARNINGS
 
SOURCES += main.cpp
 
# Default rules for deployment.
qnx: target.path = /tmp/$${TARGET}/bin
else: unix:!android: target.path = /opt/$${TARGET}/bin
!isEmpty(target.path): INSTALLS += target

main.cpp

#include <iostream>
#include <QtCore>
#include <QThread>
#include <QtNetwork>
#include <QtConcurrent>
// ──────────────────────────────────────────────────────────────────────────────────
class JsonWorker : public QObject {
    Q_OBJECT
    QString Url;
    QNetworkAccessManager M;
    QNetworkReply *Rep;
    QJsonDocument Json;
  public:
    JsonWorker(QString iUrl = ""): Url(iUrl) {}
    QJsonDocument Get() {
      QNetworkRequest Req(Url);
      Rep = M.get(Req);
      QEventLoop Loop;
      connect(Rep, &QNetworkReply::finished, this, &JsonWorker::finish);
      connect(Rep, &QNetworkReply::errorOccurred, this, &JsonWorker::error);
      // ────────────────────────────────────────────────────────────────────────────
      // Прогресс закоментил, чтобы не засорять вывод
      // connect(Rep, &QNetworkReply::downloadProgress, this, &JsonWorker::progress);
      // ────────────────────────────────────────────────────────────────────────────
      connect(this, &JsonWorker::done, &Loop, &QEventLoop::quit);
      Loop.exec();
      return Json;
    }
  public slots:
    void finish() {
      Json = QJsonDocument::fromJson(Rep->readAll());
      emit done();
    }
    void error(QNetworkReply::NetworkError code) {
      std::cout << "Worker net error: " << code;
    }
    void progress(qint64 bytesReceived, qint64 bytesTotal) {
      std::cout << "Worker process: " << bytesReceived << "/" << bytesTotal;
    }
  signals:
    void done();
};
// ──────────────────────────────────────────────────────────────────────────────────
class JsonReader : public QObject {
    Q_OBJECT
  public:
    QFuture<QJsonDocument> read(const QString& iUrl) {
      auto lambdaJsonWorker = [&](const QString & iUrl) {
        JsonWorker Worker(iUrl);
        return Worker.Get();
      };
      return QtConcurrent::run(lambdaJsonWorker, iUrl);
    };
};
// ──────────────────────────────────────────────────────────────────────────────────
class NetTask : public QObject {
    Q_OBJECT
  public:
    QString Url;
    JsonReader Reader;
    QFuture<QJsonDocument> Future;
    NetTask(QObject *parent = 0, QString url = "") : QObject(parent), Url(url) {}
  public slots:
    void run() {
      QFutureWatcher<QJsonDocument> *Watcher =
        new QFutureWatcher<QJsonDocument>(this);
      Future = Reader.read(Url);
      Watcher->setFuture(Future);
      Watcher->waitForFinished();
      delete Watcher;
      emit ready();
    }
    void print() {
      QJsonDocument Json = Future.result();
      std::cout << Json.toJson(QJsonDocument::Indented).constData();
      emit done();
    }
  signals:
    void ready();
    void done();
};
// ──────────────────────────────────────────────────────────────────────────────────
#include "main.moc" // <--- так как Q_OBJECT залепил в самом "main.cpp"
// ──────────────────────────────────────────────────────────────────────────────────
int main(int argc, char *argv[]) {
  #ifdef QT_NO_CONCURRENT
  #error "Ups!"
  #else
  QCoreApplication a(argc, argv);
  NetTask *task = new NetTask(&a, "http://testo/index.php");
  QObject::connect(task, &NetTask::ready, task, &NetTask::print);
  QObject::connect(task, &NetTask::done, &a, &QCoreApplication::quit);
  QTimer::singleShot(0, task, &NetTask::run);
  return a.exec();
  #endif
}
Рейтинг: 0/5 - 0 голосов