技术专栏
Qt软件更新(二)
Qt软件更新(二)
本篇文章介绍的是上一篇提到的下载功能,通过http URL 地址下载文件
用法原理:
1、使用QNetworkAccessManager的get方法,得到QNetworkReply
2、通过QNetworkReply其readAll方法,取得其中的QByteArray,即为下载的数据
3、利用QFile(QTemporaryFile)的write方法将数据写到磁盘上
实现功能:
添加下载地址到下载列表中,启动下载,依次下载文件
代码实现:
注意:如果新建工程时没有添加QtNetwork模块,那么就要手动在工程文件.pro中添加代码
QT += network
表明我们使用了网络模块。
#ifndef QDOWNLOAD_H
#define QDOWNLOAD_H
#include <QObject>
#include <QtNetwork>
class QDownload : public QObject
{
Q_OBJECT
public:
explicit QDownload(QObject *parent = nullptr);
QNetworkAccessManager manager;
QMap<QNetworkReply*,QString> currentDownloads;
void doDownload(const QUrl &url,QString saveUrl = "");
static QString saveFileName(const QUrl &url,QString saveRoute = "");
bool saveToDisk(const QString &filename, QIODevice *data);
static bool isHttpRedirect(QNetworkReply *reply);
private:
struct downLoadStruct{
QUrl url;//下载地址
QString saveUrl;//保存路径
};
QList<downLoadStruct> downLoadQueue;
public slots:
void downloadFinished(QNetworkReply *reply);
void sslErrors(const QList<QSslError> &errors);
void downloadProgress(qint64 bytesReceived, qint64 bytesTotal);
void doDownload();
signals:
void downloadFinished(QString downloadURL,QString saveURL);
void downloadProgress(QString url,qint64 percent);
public slots:
};
#endif // QDOWNLOAD_H
#include "qdownload.h"
QDownload::QDownload(QObject *parent) : QObject(parent)
{
connect(&manager, SIGNAL(finished(QNetworkReply*)),
SLOT(downloadFinished(QNetworkReply*)));
}
void QDownload::doDownload(const QUrl &url,QString saveUrl)
{
if(!downLoadQueue.isEmpty() || !currentDownloads.isEmpty())
{
downLoadStruct newDl;
newDl.url = url;
newDl.saveUrl = saveUrl;
downLoadQueue.append(newDl);
return;
}
QNetworkRequest request(url);
QSslConfiguration config = QSslConfiguration::defaultConfiguration();
config.setPeerVerifyMode(QSslSocket::VerifyNone);
config.setProtocol(QSsl::TlsV1SslV3);
request.setSslConfiguration(config);
QNetworkReply *reply = manager.get(request);
connect(reply,SIGNAL(downloadProgress(qint64,qint64)),this,SLOT(downloadProgress(qint64,qint64)));
#if QT_CONFIG(ssl)
connect(reply, SIGNAL(sslErrors(QList<QSslError>)),
SLOT(sslErrors(QList<QSslError>)));
#endif
currentDownloads.insert(reply,saveUrl);
}
QString QDownload::saveFileName(const QUrl &url,QString saveRoute)
{
QString path = url.path();
QString basename = QFileInfo(path).fileName();
if (basename.isEmpty())
basename = "download";
if(saveRoute.isEmpty())
saveRoute = QDir::currentPath();
//如果路径不存在,则创建
QDir* dir = new QDir();
if(!dir->exists(saveRoute)){
dir->mkpath(saveRoute);
}
basename = saveRoute + basename;
if (QFile::exists(basename)) {
}
return basename;
}
bool QDownload::saveToDisk(const QString &filename, QIODevice *data)
{
QFile file(filename);
if (!file.open(QIODevice::WriteOnly)) {
fprintf(stderr, "Could not open %s for writing: %s\n",
qPrintable(filename),
qPrintable(file.errorString()));
return false;
}
file.write(data->readAll());
file.close();
return true;
}
bool QDownload::isHttpRedirect(QNetworkReply *reply)
{
int statusCode = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
return statusCode == 301 || statusCode == 302 || statusCode == 303
|| statusCode == 305 || statusCode == 307 || statusCode == 308;
}
void QDownload::doDownload()
{
if(downLoadQueue.isEmpty())
return;
downLoadStruct newDl = downLoadQueue.first();
downLoadQueue.removeFirst();
QNetworkRequest request(newDl.url);
QSslConfiguration config = QSslConfiguration::defaultConfiguration();
config.setPeerVerifyMode(QSslSocket::VerifyNone);
config.setProtocol(QSsl::TlsV1SslV3);
request.setSslConfiguration(config);
QNetworkReply *reply = manager.get(request);
connect(reply,SIGNAL(downloadProgress(qint64,qint64)),this,SLOT(downloadProgress(qint64,qint64)));
#if QT_CONFIG(ssl)
connect(reply, SIGNAL(sslErrors(QList<QSslError>)),
SLOT(sslErrors(QList<QSslError>)));
#endif
}
void QDownload::sslErrors(const QList<QSslError> &sslErrors)
{
#if QT_CONFIG(ssl)
for (const QSslError &error : sslErrors)
fprintf(stderr, "SSL error: %s\n", qPrintable(error.errorString()));
#else
Q_UNUSED(sslErrors);
#endif
}
void QDownload::downloadProgress(qint64 bytesReceived, qint64 bytesTotal)
{
qint64 Progress = static_cast<qint64>(static_cast<double>(bytesReceived)/static_cast<double>(bytesTotal)*100);
emit downloadProgress(currentDownloads.begin().key()->url().toString(),Progress);
}
void QDownload::downloadFinished(QNetworkReply *reply)
{
QUrl url = reply->url();
if (reply->error()) {
qDebug() << "Download of " << url.toString() << " failed:" << qPrintable(reply->errorString());
} else {
if (isHttpRedirect(reply)) {
// fputs("Request was redirected.\n", stderr);
qDebug() << "Request was redirected.\n" << stderr;
} else {
QString filename = saveFileName(url,currentDownloads.contains(reply) ? currentDownloads.find(reply).value() : "");
if (saveToDisk(filename, reply)) {
printf("Download of %s succeeded (saved to %s)\n",
url.toEncoded().constData(), qPrintable(filename));
QDir d(filename);
QTimer::singleShot(0,this,SLOT(doDownload()));
emit downloadFinished(url.toString(),d.absolutePath());
}
}
}
currentDownloads.remove(reply);
reply->deleteLater();
}
声明:本文内容由易百纳平台入驻作者撰写,文章观点仅代表作者本人,不代表易百纳立场。如有内容侵权或者其他问题,请联系本站进行删除。
红包
43
15
评论
打赏
- 分享
- 举报
评论
0个
手气红包
暂无数据
相关专栏
-
浏览量:7738次2020-11-25 22:46:18
-
浏览量:10090次2020-11-24 23:33:27
-
浏览量:2046次2018-02-01 18:47:33
-
浏览量:3392次2020-08-18 20:09:59
-
浏览量:622次2023-07-28 10:19:40
-
浏览量:1241次2022-12-16 12:31:41
-
浏览量:4213次2020-10-28 23:08:53
-
浏览量:5395次2020-08-23 21:07:51
-
浏览量:2514次2020-02-29 10:14:49
-
浏览量:2551次2022-03-05 09:18:25
-
浏览量:4835次2020-08-11 18:51:18
-
浏览量:10524次2020-08-30 00:41:53
-
浏览量:591次2023-08-18 09:40:15
-
浏览量:4979次2020-09-30 18:03:58
-
浏览量:691次2023-09-18 10:32:50
-
浏览量:3338次2021-09-30 15:01:23
-
浏览量:1748次2020-05-09 09:32:48
-
浏览量:3826次2020-08-21 19:40:26
-
浏览量:3163次2020-08-22 16:09:02
置顶时间设置
结束时间
删除原因
-
广告/SPAM
-
恶意灌水
-
违规内容
-
文不对题
-
重复发帖
打赏作者
小王子🤴
您的支持将鼓励我继续创作!
打赏金额:
¥1
¥5
¥10
¥50
¥100
支付方式:
微信支付
打赏成功!
感谢您的打赏,如若您也想被打赏,可前往 发表专栏 哦~
举报反馈
举报类型
- 内容涉黄/赌/毒
- 内容侵权/抄袭
- 政治相关
- 涉嫌广告
- 侮辱谩骂
- 其他
详细说明
审核成功
发布时间设置
发布时间:
请选择发布时间设置
是否关联周任务-专栏模块
审核失败
失败原因
请选择失败原因
备注
请输入备注