Qt Forum

    • Login
    • Search
    • Categories
    • Recent
    • Tags
    • Popular
    • Users
    • Groups
    • Search
    • Unsolved

    Update: Forum Guidelines & Code of Conduct

    [SOLVED] QNetworkReply and lambda -- strange behaviour

    General and Desktop
    4
    9
    4059
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • V
      vmkan last edited by

      Hi there!

      I'm trying to write a simple network function. Now it looks like that:

      @void NetworkManager::getClanInfoByTag(const QString &tag)
      {
      QNetworkRequest request = QNetworkRequest(QUrl(clanInfoUrl.arg(appId).arg(tag)));

      QNetworkReply* reply = m_manager->get(request);
      
      connect(reply, &QNetworkReply::finished, [this, reply]()
      {
          qDebug() << sender();
          qDebug() << reply->errorString();
          qDebug() << reply->readAll();
      
          emit clanInfoByTagCompleted(reply->readAll(),
                                      reply->error() == QNetworkReply::NoError);
      });
      
      reply->deleteLater();
      

      }@

      So, I'm simply trying to request data by some url and print it. I know, that QNetworkAccessManager is asynchronous, so I wrote lambda instead of separate slot...and it doesn't work. No data in output of program. However, if
      @reply->deleteLater()@

      is commented, then qDebug prints

      QObject(0x0)
      "Unknown error"
      some valid data

      m_manager is declared as QNetworkAccessManager* inside my NetworkManager class.

      What am I doing wrong?
      Should I write separate slot for that?
      Thanks to any help.

      1 Reply Last reply Reply Quote 0
      • SGaist
        SGaist Lifetime Qt Champion last edited by

        Hi,

        You are calling deleteLater directly in getClanInfoByTag rather that in the lambda which means that at the next event loop iteration your reply will be deleted. deleteLater won't wait for the lambda to be called or the reply to finish.

        Interested in AI ? www.idiap.ch
        Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

        1 Reply Last reply Reply Quote 0
        • V
          vmkan last edited by

          [quote author="SGaist" date="1420321593"]Hi,

          You are calling deleteLater directly in getClanInfoByTag rather that in the lambda which means that at the next event loop iteration your reply will be deleted. deleteLater won't wait for the lambda to be called or the reply to finish.[/quote]

          Thanks, that seemes interesting! But after I've tried it, the output looks like in second case:

          QObject(0×0)
          “Unknown error”
          some valid data

          So, the problem is still present.

          1 Reply Last reply Reply Quote 0
          • T
            t3685 last edited by

            Shouldn't the third argument be a QObject? It looks like you only have three arguments.

            1 Reply Last reply Reply Quote 0
            • C
              ckakman last edited by

              Hi,

              What do you consider as a problem?

              If you consider that sender() returns a null pointer as a problem, according to the "documentation":http://doc.qt.io/qt-5/qobject.html#sender , it seems to be the expected behavior. sender() returns a valid pointer when called in a slot.

              By the way, since "reply" is captured in the lambda, you don't need sender(). You already have the sender of the signal, i.e. "reply".

              If you consider not receiving any data as a problem, than SGaist has already given the answer for that. You should put the reply->deleteLater() into the lambda. Otherwise you'll have a logical error by deleting the "reply" object before receiving any reply.

              As for the address of the "reply" object, replace the first line of the lambda as follows:
              @qDebug() << reply;@

              1 Reply Last reply Reply Quote 0
              • C
                ckakman last edited by

                Aha, there is another issue in your code: You are calling reply->readAll() twice. You should call it once and store the returned data in a variable and than you should use it twice:
                @
                ...
                QByteArray data = reply->readAll();
                qDebug() << data;
                emit clanInfoByTagCompleted(data, ...);
                ...
                @

                1 Reply Last reply Reply Quote 0
                • V
                  vmkan last edited by

                  [quote author="ckakman" date="1420325742"]Aha, there is another issue in your code: You are calling reply->readAll() twice. You should call it once and store the returned data in a variable and than you should use it twice:
                  @
                  ...
                  QByteArray data = reply->readAll();
                  qDebug() << data;
                  emit clanInfoByTagCompleted(data, ...);
                  ...
                  @[/quote]

                  No, that's just for debugging =)

                  [quote author="ckakman" date="1420325513"]Hi,
                  What do you consider as a problem?
                  [/quote]

                  The main problem here -- "Unknown error", while reply->readAll() gives me valid QByteArray =(

                  [quote author="t3685" date="1420325393"]Shouldn't the third argument be a QObject? It looks like you only have three arguments.[/quote]

                  Qt supports lambda functions as slot functions, and in that case, only 3 arguments will be provided. Otherwise, that code shouldn't be compiled =)

                  1 Reply Last reply Reply Quote 0
                  • C
                    ckakman last edited by

                    Look at the QIODevice "source code":https://qt.gitorious.org/qt/qtbase/source/73a1e8c60d894701f34806cc4b847aa2814bf389:src/corelib/io/qiodevice.cpp :line 1618

                    If the error string is empty, "Unknown error" is returned. Apparently, you should call errorString() when error() returns something other than NoError. That makes sense.

                    1 Reply Last reply Reply Quote 0
                    • V
                      vmkan last edited by

                      [quote author="ckakman" date="1420329539"]Look at the QIODevice "source code":https://qt.gitorious.org/qt/qtbase/source/73a1e8c60d894701f34806cc4b847aa2814bf389:src/corelib/io/qiodevice.cpp :line 1618

                      If the error string is empty, "Unknown error" is returned. Apparently, you should call errorString() when error() returns something other than NoError. That makes sense.[/quote]

                      Oh, my fault. Thank you! Everything works fine.

                      1 Reply Last reply Reply Quote 0
                      • First post
                        Last post