Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

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



  • 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



  • @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...



  • 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 !


Log in to reply