QT – 如何通过HTTP下载和保存图像?

我试图用控制台应用程序下载和保存一些图像。 这是我到目前为止,(所有代码正在编译,但运行后,似乎不进入replyFinished()函数…)

 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..."; } 

使用QNetworkAccessManager下载图像

头文件

 #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 

源文件

 #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(); } } 

头文件

 #ifndef IMAGEDOWNLOAD_H #define IMAGEDOWNLOAD_H #include <QWidget> #include <QHttp> #include <QFile> #include <QUrl> class ImageDownload : public QWidget { Q_OBJECT public: explicit ImageDownload(QWidget *parent = 0); private: int httpGetId; QHttp http; QFile myfile; private slots: void httpRequestFinished(int, bool); void progress(int,int); }; #endif // IMAGEDOWNLOAD_H 

源文件

 #include "imagedownload.h" ImageDownload::ImageDownload(QWidget *parent) : QWidget(parent) { QUrl url("url of image."); myfile.setFileName("C:/Qt/imagefilename"); myfile.open(QIODevice::WriteOnly); connect(&http,SIGNAL(requestFinished(int,bool)),this,SLOT(httpRequestFinished(int,bool))); connect(&http,SIGNAL(dataReadProgress(int,int)),this,SLOT(progress(int,int))); http.setHost(url.host(),QHttp::ConnectionModeHttp,url.port()); httpGetId = http.get(url.path(),&myfile); } void ImageDownload::httpRequestFinished(int id, bool error) { if(id == httpGetId) { myfile.close(); } if(error) { qDebug(http.errorString().toLatin1()); } } void ImageDownload::progress(int a, int b) { qDebug(QString::number(a).toLatin1()+" : "+QString::number(b).toLatin1()); } 

这是一个老问题,但作为参考,我会发布@ lwinhtooko的代码的工作版本:

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; } 

这个问题似乎是QNetworkReply被使用的方式。