I have a very confusing problem.
I had a simple project that was downloading files from some ftp servers. It worked very good.
Then, I tried implementing that same code into a larger project (first one was a Console App, and the second one is GUI, but I don't think that changes anything..).
After doing some debugging it seems to me that finished()
signal from QNetworkAccessManager
somehow never gets emitted (or received).
Again, the exact same lines of code work as a separate project.
downloader.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
downloader.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 (important part)
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()));
}
Can't get my head around this.
Any help is welcome,
Thanks!
EDIT> More info: Debugger posts this>
url, debug
entry: doDownload
exit: doDownload
You create object Downloader
on stack and it is deleted right after your function exits. You must create object using new
, and provide MainWindow
object as parent, so after you close MainWindow, the object will be destroyed.
If the download finish, you still need to destroy the object, so simply connect the dloadend()
signal to deleteLater()
slot, Qt loop will delete your object right after all signal are processed.
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()));
}