参考 :http://www.cppblog.com/gaimor/archive/2011/11/16/160289.html
#ifndef DOWMLOADWIDGET_H #define DOWMLOADWIDGET_H #include <QWidget> #include <QProgressDialog> #include <QUrl> #include <QNetworkAccessManager> #include <QNetworkReply> #include <QFile> namespace Ui { class DowmloadWidget; } class DowmloadWidget : public QWidget { Q_OBJECT public: explicit DowmloadWidget(QWidget *parent = 0); ~DowmloadWidget(); void startRequest(QUrl url); private slots: void downloadFile(); void cancelDownload(); void httpFinished(); void httpReadyRead(); void updateDataReadProgress(qint64 bytesRead, qint64 totalBytes); void enableDownloadButton(); void slotAuthenticationRequired(QNetworkReply*,QAuthenticator *); private: // QLabel *statusLabel; // QLabel *urlLabel; // QLineEdit *urlLineEdit; QProgressDialog *progressDialog; // QPushButton *downloadButton; // QPushButton *quitButton; // QDialogButtonBox *buttonBox; QUrl url; QNetworkAccessManager qnam; QNetworkReply *reply; QFile *file; int httpGetId; bool httpRequestAborted; private: Ui::DowmloadWidget *ui; }; #endif // DOWMLOADWIDGET_H
#include "dowmloadwidget.h" #include "ui_dowmloadwidget.h" #include <QFileInfo> #include <QMessageBox> #include <QThread> DowmloadWidget::DowmloadWidget(QWidget *parent) : QWidget(parent), ui(new Ui::DowmloadWidget) { progressDialog = NULL; reply = NULL; ui->setupUi(this); connect(ui->downloadButton, &QPushButton::clicked, this,&DowmloadWidget::downloadFile); connect(ui->quitButton, &QPushButton::clicked, this, &DowmloadWidget::cancelDownload); } DowmloadWidget::~DowmloadWidget() { delete ui; } void DowmloadWidget::startRequest(QUrl url) { reply = qnam.get(QNetworkRequest(url)); connect(reply, SIGNAL(finished()),this, SLOT(httpFinished())); connect(reply, SIGNAL(readyRead()),this, SLOT(httpReadyRead())); connect(reply, SIGNAL(downloadProgress(qint64,qint64)),this, SLOT(updateDataReadProgress(qint64,qint64))); } void DowmloadWidget::downloadFile() { url = ui->urlLineEdit->text(); QFileInfo fileInfo(url.path()); QString fileName = fileInfo.fileName(); // fileName = "downloadfile.dat"; if(fileName.isEmpty()) fileName = "index.html"; if(QFile::exists(fileName)) { if (QMessageBox::question(this, tr("HTTP"), 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, tr("HTTP"), tr("Unable to save the file %1: %2.") .arg(fileName).arg(file->errorString())); delete file; file = 0; return; } if(progressDialog == NULL) { progressDialog = new QProgressDialog(this); } progressDialog->show(); progressDialog->setWindowTitle(tr("HTTP")); progressDialog->setLabelText(tr("Downloading %1.").arg(fileName)); ui->downloadButton->setEnabled(false); // schedule the request httpRequestAborted = false; startRequest(url); } void DowmloadWidget::cancelDownload() { if(reply == NULL) return; if(reply->isFinished()) return; reply->abort(); ui->statusLabel->setText(tr("Download canceled.")); httpRequestAborted = true; ui->downloadButton->setEnabled(true); } void DowmloadWidget::httpFinished() { if (httpRequestAborted) { if (file) { file->close(); file->remove(); delete file; file = NULL; } reply->deleteLater(); progressDialog->hide(); return; } progressDialog->hide(); file->flush(); file->close(); QVariant redirectionTarget = reply->attribute(QNetworkRequest::RedirectionTargetAttribute); if (reply->error()) { file->remove(); QMessageBox::information(this, tr("HTTP"), tr("Download failed: %1.") .arg(reply->errorString())); ui->downloadButton->setEnabled(true); } else if (!redirectionTarget.isNull()) { QUrl newUrl = url.resolved(redirectionTarget.toUrl()); if (QMessageBox::question(this, tr("HTTP"), tr("Redirect to %1 ?").arg(newUrl.toString()), QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes) { url = newUrl; reply->deleteLater(); file->open(QIODevice::WriteOnly); file->resize(0); startRequest(url); return; } } else { QString fileName = QFileInfo(QUrl(ui->urlLineEdit->text()).path()).fileName(); ui->statusLabel->setText(tr("Downloaded %1 to current directory.").arg(fileName)); ui->downloadButton->setEnabled(true); } reply->deleteLater(); reply = NULL; delete file; file = NULL; } void DowmloadWidget::httpReadyRead() { // this slot gets called every time the QNetworkReply has new data. // We read all of its new data and write it into the file. // That way we use less RAM than when reading it at the finished() // signal of the QNetworkReply if (file) file->write(reply->readAll()); } void DowmloadWidget::updateDataReadProgress(qint64 bytesRead, qint64 totalBytes) { if (httpRequestAborted) return; progressDialog->setMaximum(totalBytes); progressDialog->setValue(bytesRead); } void DowmloadWidget::enableDownloadButton() {} void DowmloadWidget::slotAuthenticationRequired(QNetworkReply*,QAuthenticator *) {}