I am trying to download and save some images with Qt in a console appplication. Here is what I got so far, (all code is compiling, but after run, it seems to don't enter to replyFinished()
function...)
void Test::start()
{
std::cout << "start1";
QNetworkAccessManager *manager = new QNetworkAccessManager();
connect(manager, SIGNAL(finished(QNetworkReply*)), this, SLOT(replyFinished(QNetworkReply*)));
manager->get(QNetworkRequest(QUrl("http://www.exylum.mydevil.net/firefox.jpg")));
}
void Test::replyFinished(QNetworkReply* reply)
{
std::cout << "st";
QImage* img2 = new QImage();
img2->loadFromData(reply->readAll());
if(img2->isNull())
std::cout << "oops";
if(img2->save("omg2.jpg", "JPG"))
std::cout << "saved";
else
std::cout << "dont...";
}
Download Image using QNetworkAccessManager
header file
#ifndef QDOWNLOADER_H
#define QDOWNLOADER_H
#include <QObject>
#include <QNetworkAccessManager>
#include <QNetworkRequest>
#include <QNetworkReply>
#include <QFile>
#include <QStringList>
class QDownloader : public QObject
{
Q_OBJECT
public:
explicit QDownloader(QObject *parent = 0);
virtual ~QDownloader();
void setFile(QString fileURL);
private:
QNetworkAccessManager *manager;
QNetworkReply *reply;
QFile *file;
private slots:
void onDownloadProgress(qint64,qint64);
void onFinished(QNetworkReply*);
void onReadyRead();
void onReplyFinished();
};
#endif // QDOWNLOADER_H
source file
#include "qdownloader.h"
QDownloader::QDownloader(QObject *parent) :
QObject(parent)
{
manager = new QNetworkAccessManager;
}
QDownloader::~QDownloader()
{
manager->deleteLater();
}
void QDownloader::setFile(QString fileURL)
{
QString filePath = fileURL;
QString saveFilePath;
QStringList filePathList = filePath.split('/');
QString fileName = filePathList.at(filePathList.count() - 1);
saveFilePath = QString("C:/Images/" + fileName );
QNetworkRequest request;
request.setUrl(QUrl(fileURL));
reply = manager->get(request);
file = new QFile;
file->setFileName(saveFilePath);
file->open(QIODevice::WriteOnly);
connect(reply,SIGNAL(downloadProgress(qint64,qint64)),this,SLOT(onDownloadProgress(qint64,qint64)));
connect(manager,SIGNAL(finished(QNetworkReply*)),this,SLOT(onFinished(QNetworkReply*)));
connect(reply,SIGNAL(readyRead()),this,SLOT(onReadyRead()));
connect(reply,SIGNAL(finished()),this,SLOT(onReplyFinished()));
}
void QDownloader::onDownloadProgress(qint64 bytesRead,qint64 bytesTotal)
{
qDebug(QString::number(bytesRead).toLatin1() +" - "+ QString::number(bytesTotal).toLatin1());
}
void QDownloader::onFinished(QNetworkReply * reply)
{
switch(reply->error())
{
case QNetworkReply::NoError:
{
qDebug("file is downloaded successfully.");
}break;
default:{
qDebug(reply->errorString().toLatin1());
};
}
if(file->isOpen())
{
file->close();
file->deleteLater();
}
}
void QDownloader::onReadyRead()
{
file->write(reply->readAll());
}
void QDownloader::onReplyFinished()
{
if(file->isOpen())
{
file->close();
file->deleteLater();
}
}
This is an old question, but for reference, I'll post a working version of @lwinhtooko's code:
downloader.h:
#pragma once
#include <QFile>
#include <QNetworkAccessManager>
#include <QNetworkRequest>
#include <QNetworkReply>
#include <QObject>
#include <QUrl>
class Downloader : public QObject {
Q_OBJECT
QFile *m_file;
bool m_isReady = true;
public:
explicit Downloader(QObject *parent = 0) : QObject(parent) {}
virtual ~Downloader() { delete m_file; }
void downloadFileFromURL(const QString &url, const QString &filePath);
private slots:
void onDownloadFileComplete(QNetworkReply *reply);
};
downloader.cpp:
#include "downloader.h"
void Downloader::downloadFileFromURL(const QString &url, const QString &filePath) {
if (!m_isReady)
return;
m_isReady = false;
const QString fileName = filePath + url.right(url.size() - url.lastIndexOf("/")); // your filePath should end with a forward slash "/"
m_file = new QFile();
m_file->setFileName(fileName);
m_file->open(QIODevice::WriteOnly);
if (!m_file->isOpen()) {
m_isReady = true;
return; // TODO: permission check?
}
QNetworkAccessManager *manager = new QNetworkAccessManager;
QNetworkRequest request;
request.setUrl(QUrl(url));
connect(manager, SIGNAL(finished(QNetworkReply *)), this, SLOT(onDownloadFileComplete(QNetworkReply *)));
manager->get(request);
}
void Downloader::onDownloadFileComplete(QNetworkReply *reply) {
if (!m_file->isWritable()) {
m_isReady = true;
return; // TODO: error check
}
m_file->write(reply->readAll());
m_file->close(); // TODO: delete the file from the system later on
m_isReady = true;
}
The issue appeared to be the way QNetworkReply
was being used.
None of above solution didn't work for me. But i found this Qt wiki page that worked perfectly for all type of data.
Download Data from URL
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With