Невозможно использовать QNetworkAccessManager с QtConcurrent

Я пытаюсь использовать QtConcurrent, чтобы не создавать новый слот для простого запроса QNetworkAccessManager::get:

QNetworkAccessManager *am = new QNetworkAccessManager();
QFuture<QNetworkReply*> future = QtConcurrent::run(am, &QNetworkAccessManager::get, QNetworkRequest(QUrl("https://api.ipify.org/?format=json")));
future.waitForFinished();

но я получаю предупреждение от Qt:

QObject: Невозможно создать дочерние элементы для родителя, находящегося в другом потоке.

(Родительский поток — QNetworkAccessManager(0x7fc973f3d100), родительский поток — QThread(0x7fc973c14ec0), текущий поток — QThread(0x7fc973dc2090)

Если код типа:

QObject *obj = new QObject();
QFuture<void> future = QtConcurrent::run(obj, &QObject::setParent, new QObject);
future.waitForFinished();

работает нормально и без предупреждений и ошибок, может ли кто-нибудь объяснить мне, в чем разница между двумя подходами и что происходит за кулисами подхода QNetworkAccessManager?

Есть ли решение для подхода QNetworkAccessManager?


person Jacob Krieg    schedule 28.11.2016    source источник
comment
Почему вы пытаетесь вызвать функцию get из пула потоков, а не из основного потока графического интерфейса? Обычно перемещаются функции, выполнение которых занимает много времени. get является асинхронным и предназначен для обычного запуска из потока графического интерфейса.   -  person Mike    schedule 28.11.2016
comment
Кроме того, вы, кажется, вызываете waitForFinished() сразу после запуска вызова в другом потоке. Увидев это, я вообще не мог придумать причины для распараллеливания такого вызова.   -  person Mike    schedule 28.11.2016
comment
Каждый QNetworkAccessManager предназначен для использования только из потока, в котором он был создан. это можно увидеть в документах. При вызове get Qt пытается создать объект QNetworkReply для этого запроса, и этот объект является дочерним по отношению к QNetworkAccessManager. Он не может создать такой дочерний элемент для родителя в другом потоке, отсюда и предупреждение.   -  person Mike    schedule 28.11.2016
comment
Вам не нужно создавать слот для каждого вызова get, вы можете подключиться к лямбда-функциям. Взгляните на этот ответ.   -  person Mike    schedule 28.11.2016
comment
@Mike Прочитав ваши комментарии, я теперь понимаю, какой идиотизм я пытался сделать ... Я как-то ожидал, что waitForFinished будет ждать, пока не будет испущено QNetworkReply::finished ... что очень глупо ... Так что да ... спасибо! :)   -  person Jacob Krieg    schedule 28.11.2016