Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. QNetworkAccessManager - There is an extra "finished" signal at the end
Qt 6.11 is out! See what's new in the release blog

QNetworkAccessManager - There is an extra "finished" signal at the end

Scheduled Pinned Locked Moved Solved General and Desktop
3 Posts 2 Posters 328 Views 1 Watching
  • 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.
  • Q Offline
    Q Offline
    Qtooc
    wrote on last edited by
    #1

    Hello,

    When I use a QNetworkAccessManager to download files I receive an extra / unwanted finished event.
    If I want to download 2 files, my finished slot is called 3 times...
    And the code is very simple...
    I don't see what is wrong.

    My class stores a vector of urls and variables for the current download :

    std::vector<QUrl> m_vectorUrl;
    
    std::vector<QUrl>::iterator m_currentUrlIt; // iterator on the url
    QFile *m_currentFile; // to save the downloaded document
    QNetworkReply *m_currentReply = nullptr;
    

    To download all the urls :

    void TestNetworkManager::DownloadAllUrls()
    {
        m_currentUrlIt = std::begin(m_vectorUrl);
        DownloadUrl();
    }
    

    To download an url :

    void TestNetworkManager::DownloadUrl()
    {
        // No more url to read in the vector
        if (m_currentUrlIt == std::end(m_vectorUrl))
            return;
    
        // get url in url vector
        QUrl url = *m_currentUrlIt;
    
        // open file to save the download
        QString basename = url.host();
        m_currentFile = new QFile(basename);
        m_currentFile->open(QIODevice::WriteOnly);
    
        // Init download
        QNetworkRequest request(url);
        m_currentReply = m_netManager.get(request);
    
        connect(&m_netManager, &QNetworkAccessManager::finished, this, &TestNetworkManager::Finished);
        connect(m_currentReply, &QIODevice::readyRead, this,  &TestNetworkManager::ReadData);
    }
    

    The ReadData function :

    void TestNetworkManager::ReadData()
    {
        m_currentFile->write(m_currentReply->readAll());
    }
    

    The Finished function closes the file, increments the iterator to the next url in the vector and calls again DownloadUrl ():

    void TestNetworkManager::Finished(QNetworkReply *r)
    {
        // Close file
        m_currentFile->close();
    
        // prepare current values for the next url
        delete m_currentFile;
        m_currentReply->deleteLater();
        m_currentUrlIt++; // next url in url vector
    
        // download next url
        DownloadUrl();
    }
    

    If my vector contains 2 urls the Finished function is called 3 times.
    And at the third time m_currentFile was deleted, the iterator is at the end of the vector, etc...

    When DownloadAllUrls is called my DownloadUrl is called 3 times :
    1- by DownloadAllUrls at the start
    2- by the first Finished slot call
    3- by the second Finished call : in this case DownloadUrl returns at the beginning and the connect functions are not called.

    I don't know why my Finished slot is called 3 times...
    Do you have an idea ?

    Thanks for your help

    Pablo J. RoginaP 1 Reply Last reply
    0
    • Q Qtooc

      Hello,

      When I use a QNetworkAccessManager to download files I receive an extra / unwanted finished event.
      If I want to download 2 files, my finished slot is called 3 times...
      And the code is very simple...
      I don't see what is wrong.

      My class stores a vector of urls and variables for the current download :

      std::vector<QUrl> m_vectorUrl;
      
      std::vector<QUrl>::iterator m_currentUrlIt; // iterator on the url
      QFile *m_currentFile; // to save the downloaded document
      QNetworkReply *m_currentReply = nullptr;
      

      To download all the urls :

      void TestNetworkManager::DownloadAllUrls()
      {
          m_currentUrlIt = std::begin(m_vectorUrl);
          DownloadUrl();
      }
      

      To download an url :

      void TestNetworkManager::DownloadUrl()
      {
          // No more url to read in the vector
          if (m_currentUrlIt == std::end(m_vectorUrl))
              return;
      
          // get url in url vector
          QUrl url = *m_currentUrlIt;
      
          // open file to save the download
          QString basename = url.host();
          m_currentFile = new QFile(basename);
          m_currentFile->open(QIODevice::WriteOnly);
      
          // Init download
          QNetworkRequest request(url);
          m_currentReply = m_netManager.get(request);
      
          connect(&m_netManager, &QNetworkAccessManager::finished, this, &TestNetworkManager::Finished);
          connect(m_currentReply, &QIODevice::readyRead, this,  &TestNetworkManager::ReadData);
      }
      

      The ReadData function :

      void TestNetworkManager::ReadData()
      {
          m_currentFile->write(m_currentReply->readAll());
      }
      

      The Finished function closes the file, increments the iterator to the next url in the vector and calls again DownloadUrl ():

      void TestNetworkManager::Finished(QNetworkReply *r)
      {
          // Close file
          m_currentFile->close();
      
          // prepare current values for the next url
          delete m_currentFile;
          m_currentReply->deleteLater();
          m_currentUrlIt++; // next url in url vector
      
          // download next url
          DownloadUrl();
      }
      

      If my vector contains 2 urls the Finished function is called 3 times.
      And at the third time m_currentFile was deleted, the iterator is at the end of the vector, etc...

      When DownloadAllUrls is called my DownloadUrl is called 3 times :
      1- by DownloadAllUrls at the start
      2- by the first Finished slot call
      3- by the second Finished call : in this case DownloadUrl returns at the beginning and the connect functions are not called.

      I don't know why my Finished slot is called 3 times...
      Do you have an idea ?

      Thanks for your help

      Pablo J. RoginaP Offline
      Pablo J. RoginaP Offline
      Pablo J. Rogina
      wrote on last edited by
      #2

      @Qtooc said in QNetworkAccessManager - There is an extra "finished" signal at the end:

      connect(&m_netManager, &QNetworkAccessManager::finished, this, &TestNetworkManager::Finished);

      It's not clear to me if that connection() happens inside the DownloadUrl() method.

      If so, I guess that you're duplicating the connections. You have ONE QNAM so it's enough connecting only once the finished() signal...

      Upvote the answer(s) that helped you solve the issue
      Use "Topic Tools" button to mark your post as Solved
      Add screenshots via postimage.org
      Don't ask support requests via chat/PM. Please use the forum so others can benefit from the solution in the future

      1 Reply Last reply
      3
      • Q Offline
        Q Offline
        Qtooc
        wrote on last edited by
        #3

        Oh ! You have found immediatly !
        If i had used the finished signal of the QNetworkReply the connect could be in my DownloadUrl function I think.
        But I used the QNetworkManager without really thinking at what I was doing.

        Thank you Pablo for your help !

        1 Reply Last reply
        0

        • Login

        • Login or register to search.
        • First post
          Last post
        0
        • Categories
        • Recent
        • Tags
        • Popular
        • Users
        • Groups
        • Search
        • Get Qt Extensions
        • Unsolved