Готовый сигнал Qt5 QNetworkAccessManager никогда не испускается

У меня очень запутанная проблема.

У меня был простой проект, который загружал файлы с некоторых ftp-серверов. Это сработало очень хорошо.

Затем я попытался внедрить тот же код в более крупный проект (первое было консольным приложением, а второе — графическим интерфейсом, но я не думаю, что это что-то меняет..).

После некоторой отладки мне кажется, что сигнал finished() от QNetworkAccessManager почему-то никогда не излучается (или не принимается). Опять же, одни и те же строки кода работают как отдельный проект.

загрузчик.h

#ifndef DOWNLOADER_H
#define DOWNLOADER_H

#include <QObject>
#include <QNetworkAccessManager>
#include <QNetworkRequest>
#include <QNetworkReply>
#include <QUrl>
#include <QFile>
#include <QDebug>

class Downloader : public QObject
{
    Q_OBJECT

public:
    explicit Downloader(QObject *parent = 0);



signals:

    void dloadend();
    void printed();

public slots:
    void replyFinished (QNetworkReply *reply);
    void doDownload(QUrl url);
    void printDLend();

private:
    QNetworkAccessManager *manager;
};

#endif // DOWNLOADER_H

загрузчик.cpp

#include "downloader.h"

Downloader::Downloader(QObject *parent) :
    QObject(parent)
{
}
void Downloader::doDownload(QUrl url)
{
    qDebug()<<"entry: doDownload\n";
    QNetworkRequest req(url);
    manager = new QNetworkAccessManager(this);
    connect(manager, SIGNAL(finished(QNetworkReply*)),this,SLOT(printDLend()));//SLOT(replyFinished(QNetworkReply*)));
    manager -> get(req);
    qDebug()<<"exit: doDownload\n";
}

void Downloader::replyFinished (QNetworkReply *reply)
{
    qDebug()<<"entry: reply\n";

    if(reply->error()) {
        qDebug() << "ERROR!";
        qDebug() << reply->errorString();
    }
    else

    {
        qDebug() << "Download finished!";

        QFile *file = new QFile("C:/users/jelicicm/Desktop/test1.hex");

        if(file->open(QFile::Append))
        {
            file->write(reply->readAll());
            file->flush(); file->close();
            qDebug() <<"Downloaded file size:" <<file->size() <<"Bytes";
            qDebug() <<"File name: "<< file->fileName();
;
        }
        delete file;
    }

    reply->deleteLater();
    manager->deleteLater();
    emit dloadend();

}

mainwindow.cpp (важная часть)

void MainWindow::on_actionDownloadFirmwareImage_triggered()
{
    Downloader d;

    QUrl url("ftp://ftp.xenbase.org/pub/Genomics/JGI/Xenla6.0/Xenla_6.0_JGI_Gene_Models.fasta.tgz");

    qDebug() << "url, debug";
    ui->plainTextEdit->appendPlainText(url.toDisplayString());

    d.doDownload(url);

    QObject::connect(&d,SIGNAL(dloadend()),this, SLOT(printDLend()));
}

Не могу понять это.

Любая помощь приветствуется,

Спасибо!

РЕДАКТИРОВАТЬ> Подробнее: Отладчик публикует это>

URL, отладка

запись: doСкачать

выход: doСкачать


person Rorschach    schedule 03.04.2015    source источник


Ответы (1)


Вы создаете объект Downloader в стеке, и он удаляется сразу после выхода из вашей функции. Вы должны создать объект, используя new, и предоставить объект MainWindow в качестве родителя, поэтому после закрытия MainWindow объект будет уничтожен. Если загрузка завершена, вам все равно нужно уничтожить объект, поэтому просто подключите сигнал dloadend() к слоту deleteLater(), цикл Qt удалит ваш объект сразу после обработки всех сигналов.

void MainWindow::on_actionDownloadFirmwareImage_triggered()
{
    Downloader *d = new Downloader(this);

    QUrl url("ftp://example.com/some.file.tgz");

    qDebug() << "url, debug";
    ui->plainTextEdit->appendPlainText(url.toDisplayString());

    d->doDownload(url);

    QObject::connect(d,SIGNAL(dloadend()),this, SLOT(printDLend()));
    QObject::connect(d,SIGNAL(dloadend()), d, SLOT(deleteLater()));
}
person Arpegius    schedule 03.04.2015
comment
Ты прав. Мне это вообще не приходило в голову. Спасибо! - person Rorschach; 03.04.2015