Так сказать мой набросок для Stackoverflow:
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
#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
}