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. [SOLVED] QNetworkAccessManager does not emit finished() signal
Forum Updated to NodeBB v4.3 + New Features

[SOLVED] QNetworkAccessManager does not emit finished() signal

Scheduled Pinned Locked Moved General and Desktop
10 Posts 3 Posters 13.7k 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.
  • S Offline
    S Offline
    ShadowMoses
    wrote on last edited by
    #1

    I am writing a little test program so I could figure out how QNetworkAccessManager works and get a QProgressDialog working with a download. The download appears to work as I can see it downloading in wireshark and the progress is working. However, the reply never emits finished() and I do not believe readyRead() is emitting as well. The file is not being saved for some reason and I do not know what else to do. I would really appreciate some help here.

    Here is the header:
    @#ifndef QTDOWNLOADER_H
    #define QTDOWNLOADER_H

    #include <QtGui/QMainWindow>
    #include <QProgressDialog>
    #include <QFile>
    #include <QtNetwork>
    #include <QUrl>
    #include <QTime>
    #include <QMessageBox>
    #include "ui_qtdownloader.h"

    class QtDownloader : public QMainWindow, public Ui::QtDownloaderClass
    {
    Q_OBJECT

    public:
    QtDownloader(QWidget *parent = 0, Qt::WFlags flags = 0);
    ~QtDownloader();

    public slots:
    void downloadButtonPressed();
    void downloadProgress(qint64 bytesReceived, qint64 bytesTotal);
    void downloadFinished();
    void downloadReadyRead();
    void cancelDownload();

    private:
    QNetworkAccessManager manager;
    QFile *file;
    QTime downloadTime;
    QProgressDialog *progressDialog;
    QNetworkReply *reply;
    bool downloadRequestAborted;
    };

    #endif // QTDOWNLOADER_H
    @

    And here is the source:
    @#include "qtdownloader.h"

    QtDownloader::QtDownloader(QWidget *parent, Qt::WFlags flags)
    : QMainWindow(parent, flags)
    {
    setupUi(this);
    progressDialog = new QProgressDialog(this);
    connect(downloadButton, SIGNAL(clicked()), this, SLOT(downloadButtonPressed()));
    }

    QtDownloader::~QtDownloader()
    {
    delete progressDialog;
    progressDialog = NULL;
    }

    void QtDownloader::downloadButtonPressed()
    {
    QUrl url(urlLineEdit->text());
    QString filename = QFileInfo(url.path()).fileName();

    if(QFile::exists(filename))
    {
    if(QMessageBox::question(this, tr("Downloader"),
    tr("There already exists a file called %1 in "
    "the current directory. Overwrite?").arg(filename),
    QMessageBox::Yes|QMessageBox::No, QMessageBox::No)
    == QMessageBox::No)
    return;
    QFile::remove(filename);
    }

    file = new QFile(filename);
    if(!file->open(QIODevice::WriteOnly))
    {
    QMessageBox::information(this, "Downloader",
    tr("Unable to save the file %1: %2.")
    .arg(filename).arg(file->errorString()));
    delete file;
    file = NULL;
    return;
    }

    downloadRequestAborted = false;
    reply = manager.get(QNetworkRequest(url));
    connect(reply, SIGNAL(finished()), this, SIGNAL(downloadFinished()));
    connect(reply, SIGNAL(downloadProgress(qint64,qint64)), this, SLOT(downloadProgress(qint64,qint64)));
    connect(progressDialog, SIGNAL(canceled()), this, SLOT(cancelDownload()));
    connect(reply, SIGNAL(readyRead()), SIGNAL(downloadReadyRead()));

    progressDialog->setLabelText(tr("Downloading %1...").arg(filename));
    downloadButton->setEnabled(false);
    progressDialog->exec();
    }

    void QtDownloader::downloadProgress(qint64 bytesReceived, qint64 bytesTotal)
    {
    if(downloadRequestAborted)
    return;
    progressDialog->setMaximum(bytesTotal);
    progressDialog->setValue(bytesReceived);
    }

    void QtDownloader::downloadFinished()
    {
    if(downloadRequestAborted)
    {
    if(file)
    {
    file->close();
    file->remove();
    delete file;
    file = NULL;
    }
    reply->deleteLater();
    progressDialog->hide();
    return;
    }

    progressDialog->hide();
    file->flush();
    file->close();

    if(reply->error())
    {
    //Download failed
    QMessageBox::information(this, "Download failed", tr("Failed: %1").arg(reply->errorString()));
    }

    reply->deleteLater();
    reply = NULL;
    delete file;
    file = NULL;
    }

    void QtDownloader::cancelDownload()
    {
    downloadRequestAborted = true;
    reply->abort();
    downloadButton->setEnabled(true);
    }

    void QtDownloader::downloadReadyRead()
    {
    if(file)
    file->write(reply->readAll());
    }
    @

    I know finished is not getting emitted as the download button is never re-enabled. It does however when I cancel the download. I am really at a loss of words here.

    Thank you,
    Curtis

    1 Reply Last reply
    0
    • S Offline
      S Offline
      ShadowMoses
      wrote on last edited by
      #2

      Also, if it helps, I am using Visual Studio Professional 2010 with the plugin and Qt version 4.7.3.

      1 Reply Last reply
      0
      • D Offline
        D Offline
        dakron
        wrote on last edited by
        #3

        Hi,
        You have the mistake in connect statements, please change this two lines:
        @
        connect(reply, SIGNAL(finished()), this, SIGNAL(downloadFinished()));
        connect(reply, SIGNAL(readyRead()), SIGNAL(downloadReadyRead()));
        @

        to
        @
        connect(reply, SIGNAL(finished()), this, SLOT(downloadFinished()));
        connect(reply, SIGNAL(readyRead()), this, SLOT(downloadReadyRead()));
        @

        1 Reply Last reply
        0
        • S Offline
          S Offline
          ShadowMoses
          wrote on last edited by
          #4

          Thank you dakron! Wow, can't believe I did that. You know what they say, the more eyes the better.

          Thank you again.

          1 Reply Last reply
          0
          • L Offline
            L Offline
            loladiro
            wrote on last edited by
            #5

            [quote]
            I know finished is not getting emitted as the download button is never re-enabled. It does however when I cancel the download. I am really at a loss of words here.
            [/quote]
            First of all, you are not re-enabling the button in your code if the download is complete.
            Second I would suggest you add a call to downloadReadyRead() to your downloadFinished method, just in case that signal arrives before readyRead().

            1 Reply Last reply
            0
            • L Offline
              L Offline
              loladiro
              wrote on last edited by
              #6

              [quote author="dakron" date="1310419284"]Hi,
              You have the mistake in connect statements, please change this two lines:
              @
              connect(reply, SIGNAL(finished()), this, SIGNAL(downloadFinished()));
              connect(reply, SIGNAL(readyRead()), SIGNAL(downloadReadyRead()));
              @

              to
              @
              connect(reply, SIGNAL(finished()), this, SLOT(downloadFinished()));
              connect(reply, SIGNAL(readyRead()), this, SLOT(downloadReadyRead()));
              @
              [/quote]

              Just as a side note, the this isn't needed.

              [quote]
              bool QObject::connect ( const QObject * sender, const char * signal, const char * method, Qt::ConnectionType type = Qt::AutoConnection ) const

              This function overloads connect().

              Connects signal from the sender object to this object's method.

              Equivalent to connect(sender, signal, this, method, type).
              [/quote]

              1 Reply Last reply
              0
              • S Offline
                S Offline
                ShadowMoses
                wrote on last edited by
                #7

                [quote author="loladiro" date="1310420216"][quote]
                I know finished is not getting emitted as the download button is never re-enabled. It does however when I cancel the download. I am really at a loss of words here.
                [/quote]
                First of all, you are not re-enabling the button in your code if the download is complete.
                Second I would suggest you add a call to downloadReadyRead() to your downloadFinished method, just in case that signal arrives before readyRead().
                [/quote]

                1. Yeah, I noticed I wasn't re-enabling the button after download once it was working so I already added that.
                2. When would that happen out of curiosity? When the download happens so quick (ex. small file)?

                So something like this would be more appropriate?

                @void QtDownloader::downloadFinished()
                {
                if(downloadRequestAborted)
                {
                if(file)
                {
                file->close();
                file->remove();
                delete file;
                file = NULL;
                }
                reply->deleteLater();
                progressDialog->hide();
                downloadButton->setEnabled(true);
                return;
                }

                downloadReadyRead();
                progressDialog->hide();
                downloadButton->setEnabled(true);
                file->flush();
                file->close();

                if(reply->error())
                {
                //Download failed
                QMessageBox::information(this, "Download failed", tr("Failed: %1").arg(reply->errorString()));
                }

                reply->deleteLater();
                reply = NULL;
                delete file;
                file = NULL;
                }@

                1 Reply Last reply
                0
                • L Offline
                  L Offline
                  loladiro
                  wrote on last edited by
                  #8

                  Concerning 2). I am actually not sure that it can happen (i have heard people say it does, but never experienced it myself - probably because I don't use it that much). The only way I could imagine that happening is that the order is mixed up, because of the threading within QNetworkAcccessManager. And I always thinks it's better to be safe than sorry ;)

                  1 Reply Last reply
                  0
                  • S Offline
                    S Offline
                    ShadowMoses
                    wrote on last edited by
                    #9

                    [quote author="loladiro" date="1310420290"]
                    [quote]
                    bool QObject::connect ( const QObject * sender, const char * signal, const char * method, Qt::ConnectionType type = Qt::AutoConnection ) const

                    This function overloads connect().

                    Connects signal from the sender object to this object's method.

                    Equivalent to connect(sender, signal, this, method, type).
                    [/quote]

                    [/quote]

                    I noticed they were doing that in the "HTTP":http://doc.qt.nokia.com/latest/network-http.html example is some sections, but not in the startRequest part of the code. I just didn't really look to see why. Thank you for the info.

                    1 Reply Last reply
                    0
                    • S Offline
                      S Offline
                      ShadowMoses
                      wrote on last edited by
                      #10

                      [quote author="loladiro" date="1310421072"]Concerning 2). I am actually not sure that it can happen (i have heard people say it does, but never experienced it myself - probably because I don't use it that much). The only way I could imagine that happening is that the order is mixed up, because of the threading within QNetworkAcccessManager. And I always thinks it's better to be safe than sorry ;)[/quote]

                      Fair enough, wish there was a little better explanation, but I fall in the same boat as you. Better safe then sorry :) and thank you for the information on that as well.

                      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