2

I'm trying to use QtConcurrent for not having to create a new slot for a simple QNetworkAccessManager::get request:

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

but what i get is a warning from Qt:

QObject: Cannot create children for a parent that is in a different thread.

(Parent is QNetworkAccessManager(0x7fc973f3d100), parent's thread is QThread(0x7fc973c14ec0), current thread is QThread(0x7fc973dc2090)

If code like:

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

works fine and with no warnings and errors, can anyone explain to me what's the difference between the two approaches and what happens behind the scenes of the QNetworkAccessManager approach?

Is there a solution for the QNetworkAccessManager approach?

Community
  • 1
  • 1
Jacob Krieg
  • 2,834
  • 15
  • 68
  • 140
  • 1
    Why are you trying to call the `get` function from the thread pool rather than from the main GUI thread? Normally, one moves functions that take long time to finish. `get` is an asynchronous and is designed to be run from the GUI thread normally. – Mike Nov 28 '16 at 09:39
  • 1
    Also, you seem to call `waitForFinished()` after the starting the call in the other thread immediately. After seeing that, I couldn't think of any reason for parallelizing such call at all. – Mike Nov 28 '16 at 09:45
  • 1
    Every `QNetworkAccessManager` is designed to be used only from the thread it was created. you can see that in the [docs](https://doc.qt.io/qt-5/qnetworkaccessmanager.html#details). When calling `get`, Qt tries to create a `QNetworkReply` object for this request, and this object is a child of the `QNetworkAccessManager`. It can **not** create such a child for the parent in a different thread, hence the warning. – Mike Nov 28 '16 at 09:49
  • 1
    You don't need to create a slot for every `get` call, you can connect to lambda functions. Have a look at [this answer](https://stackoverflow.com/a/39521698/2666212). – Mike Nov 28 '16 at 09:51
  • @Mike After reading your comments I now realize the idiocy I was trying to do...I was somehow expecting that `waitForFinished` waits until `QNetworkReply::finished` gets emitted...which is extremely stupid... So yea...thanks! :) – Jacob Krieg Nov 28 '16 at 10:03

0 Answers0