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

Cancel all requests being made by QNetworkAccessManager



  • QList<QUrl> urls = {
        QUrl("http://www.google.com"),
        QUrl("http://www.google.com")
    };
    
    for (const auto &url : urls) {
        auto reply = nam.get(QNetworkRequest(url));
        connect(reply, &QNetworkReply::finished, this, &MainWindow::finished);
    }
    

    Downloader::finished:

    auto reply = qobject_cast<QNetworkReply *>(sender());
    auto content = reply->readAll();
    reply->deleteLater();
    

    I wanted to create a button for the user and when the user clicks on that button it will cancel all the requests being made by QNetworkAccessManager. How can I do that?



  • I did that way:

    for (const auto &url : urls) {
        auto reply = nam.get(QNetworkRequest(url));
        connect(reply, &QNetworkReply::finished, this, &MainWindow::finished);
        connect(ui->pushButton, &QPushButton::clicked, reply, &QNetworkReply::abort);
    }
    

    and inside the replyFinished:

        auto reply = qobject_cast<QNetworkReply *>(sender());
        reply->deleteLater();
    
        if (! reply->isReadable()) {
            return;
        }
    

    Is that right or am I doing something wrong?



  • Hi @Mr-Gisa,

    connect(ui->pushButton, &QPushButton::clicked, reply, &QNetworkReply::abort);

    That should work, although it does create some overhead (no idea how much) by having to connect every network reply to the button (depends on how many concurrent replies you expect), and also means that it will only abort requests that you remembered to connect (in case, for example, you start network requests in multiple places) - this might be desirable, or undesirable depending on your application.

    Another option, which will abort all requests started from that particular network access manager, and only requiring one connection, would be something like this in the MainWindow's initialisation:

        connect(ui->pushButton, &QPushButton::clicked, [&nam]() {
            foreach (auto &reply, nam.findChildren<QNetworkReply *>()) {
                reply->abort();
            }
        });
    

    Cheers.



  • if (! reply->isReadable()) {
            return;
    }
    

    I put that in the replyFInished cause that is normally where we call reply->readAll() the thing is that when you call abort it will also call the replyFinished anyway, so I had to put that in the top to avoid going forward and trying to read something that doesn't exist. If I don't use that piece of code in the slot it shows me a message:

    QIODevice::read (QNetworkReplyHttpImpl): device not open


Log in to reply