既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上C C++开发知识点,真正体系化!
由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新
1、DownLoadManager
#include "downloadmanager.h"
#include <QFile>
#include <QDebug>
#include <QFileInfo>
#include <QDir>
#define DOWNLOAD\_FILE\_SUFFIX "\_tmp"
DownLoadManager::DownLoadManager(QObject *parent)
: QObject(parent)
, m_networkManager(NULL)
, m_url(QUrl(""))
, m_fileName("")
, m_isSupportBreakPoint(false)
, m_bytesReceived(0)
, m_bytesTotal(0)
, m_bytesCurrentReceived(0)
, m_isStop(true)
{
m_networkManager = new QNetworkAccessManager(this);
}
DownLoadManager::~DownLoadManager()
{}
// 设置是否支持断点续传;
void DownLoadManager::setDownInto(bool isSupportBreakPoint)
{
m_isSupportBreakPoint = isSupportBreakPoint;
}
// 获取当前下载链接;
QString DownLoadManager::getDownloadUrl()
{
return m_url.toString();
}
// 开始下载文件,传入下载链接和文件的路径;
void DownLoadManager::downloadFile(QString url , QString fileName)
{
// 防止多次点击开始下载按钮,进行多次下载,只有在停止标志变量为true时才进行下载;
if (m_isStop)
{
m_isStop = false;
m_url = QUrl(url);
// 这里可用从url中获取文件名,但不是对所有的url都有效;
// QString fileName = m\_url.fileName();
// 将当前文件名设置为临时文件名,下载完成时修改回来;
m_fileName = fileName + DOWNLOAD_FILE_SUFFIX;
// 如果当前下载的字节数为0那么说明未下载过或者重新下载
// 则需要检测本地是否存在之前下载的临时文件,如果有则删除
if (m_bytesCurrentReceived <= 0)
{
removeFile(m_fileName);
}
QNetworkRequest request;
request.setUrl(m_url);
// 如果支持断点续传,则设置请求头信息
if (m_isSupportBreakPoint)
{
QString strRange = QString("bytes=%1-").arg(m_bytesCurrentReceived);
request.setRawHeader("Range", strRange.toLatin1());
}
// 请求下载;
m_reply = m_networkManager->get(request);
connect(m_reply, SIGNAL(downloadProgress(qint64, qint64)), this, SLOT(onDownloadProgress(qint64, qint64)));
connect(m_reply, SIGNAL(readyRead()), this, SLOT(onReadyRead()));
connect(m_reply, SIGNAL(finished()), this, SLOT(onFinished()));
connect(m_reply, SIGNAL(error(QNetworkReply::NetworkError)), this, SLOT(onError(QNetworkReply::NetworkError)));
}
}
// 下载进度信息;
void DownLoadManager::onDownloadProgress(qint64 bytesReceived, qint64 bytesTotal)
{
if (!m_isStop)
{
m_bytesReceived = bytesReceived;
m_bytesTotal = bytesTotal;
// 更新下载进度;(加上 m\_bytesCurrentReceived 是为了断点续传时之前下载的字节)
emit signalDownloadProcess(m_bytesReceived + m_bytesCurrentReceived, m_bytesTotal + m_bytesCurrentReceived);
}
}
// 获取下载内容,保存到文件中;
void DownLoadManager::onReadyRead()
{
if (!m_isStop)
{
QFile file(m_fileName);
if (file.open(QIODevice::WriteOnly | QIODevice::Append))
{
file.write(m_reply->readAll());
}
file.close();
}
}
// 下载完成;
void DownLoadManager::onFinished()
{
m_isStop = true;
// http请求状态码;
QVariant statusCode = m_reply->attribute(QNetworkRequest::HttpStatusCodeAttribute);
if (m_reply->error() == QNetworkReply::NoError)
{
// 重命名临时文件;
QFileInfo fileInfo(m_fileName);
if (fileInfo.exists())
{
int index = m_fileName.lastIndexOf(DOWNLOAD_FILE_SUFFIX);
QString realName = m_fileName.left(index);
QFile::rename(m_fileName, realName);
}
}
else
{
// 有错误输出错误;
QString strError = m_reply->errorString();
qDebug() << "\_\_\_\_\_\_\_\_\_\_" + strError;
}
emit signalReplyFinished(statusCode.toInt());
}
// 下载过程中出现错误,关闭下载,并上报错误,这里未上报错误类型,可自己定义进行上报;
void DownLoadManager::onError(QNetworkReply::NetworkError code)
{
QString strError = m_reply->errorString();
qDebug() << "\_\_\_\_\_\_\_\_\_\_" + strError;
closeDownload();
emit signalDownloadError();
}
// 停止下载工作;
void DownLoadManager::stopWork()
{
m_isStop = true;
if (m_reply != NULL)
{
disconnect(m_reply, SIGNAL(downloadProgress(qint64, qint64)), this, SLOT(onDownloadProgress(qint64, qint64)));
disconnect(m_reply, SIGNAL(readyRead()), this, SLOT(onReadyRead()));
disconnect(m_reply, SIGNAL(finished()), this, SLOT(onFinished()));
disconnect(m_reply, SIGNAL(error(QNetworkReply::NetworkError)), this, SLOT(onError(QNetworkReply::NetworkError)));
m_reply->abort();
m_reply->deleteLater();
m_reply = NULL;
}
}
// 暂停下载按钮被按下,暂停当前下载;
void DownLoadManager::stopDownload()
{
// 这里m\_isStop变量为了保护多次点击暂停下载按钮,导致m\_bytesCurrentReceived 被不停累加;
if (!m_isStop)
{
//记录当前已经下载字节数
m_bytesCurrentReceived += m_bytesReceived;
stopWork();
}
}
// 重置参数;
void DownLoadManager::reset()
{
m_bytesCurrentReceived = 0;
m_bytesReceived = 0;
m_bytesTotal = 0;
}
// 删除文件;
void DownLoadManager::removeFile(QString fileName)
{
// 删除已下载的临时文件;
QFileInfo fileInfo(fileName);
if (fileInfo.exists())
{
QFile::remove(fileName);
}
}
// 停止下载按钮被按下,关闭下载,重置参数,并删除下载的临时文件;
void DownLoadManager::closeDownload()
{
stopWork();
reset();
removeFile(m_fileName);
}
2、MyHttpDownload
#include "myhttpdownload.h"
#include "downloadmanager.h"
#include <QDebug>
#define UNIT\_KB 1024 //KB
#define UNIT\_MB 1024\*1024 //MB
#define UNIT\_GB 1024\*1024\*1024 //GB
#define TIME\_INTERVAL 300 //0.3s
MyHttpDownload::MyHttpDownload(QWidget *parent)
: QWidget(parent)
, m_downloadManager(NULL)
, m_url("")
, m_timeInterval(0)
, m_currentDownload(0)
, m_intervalDownload(0)
{
ui.setupUi(this);
initWindow();
}
MyHttpDownload::~MyHttpDownload()
{
}
void MyHttpDownload::initWindow()
{
ui.progressBar->setValue(0);
connect(ui.pButtonStart, SIGNAL(clicked()), this, SLOT(onStartDownload()));
connect(ui.pButtonStop, SIGNAL(clicked()), this, SLOT(onStopDownload()));
connect(ui.pButtonClose, SIGNAL(clicked()), this, SLOT(onCloseDownload()));
// 进度条设置样式;
ui.progressBar->setStyleSheet("\
QProgressBar\
{\
border-width: 0 10 0 10;\
border-left: 1px, gray;\
border-right: 1px, gray;\
border-image:url(:/Resources/progressbar\_back.png);\
}\
QProgressBar::chunk\
{\
border-width: 0 10 0 10;\
border-image:url(:/Resources/progressbar.png);\
}");
}
// 开始下载;
void MyHttpDownload::onStartDownload()
{
// 从界面获取下载链接;
m_url = ui.downloadUrl->text();
if (m_downloadManager == NULL)
{
m_downloadManager = new DownLoadManager(this);
connect(m_downloadManager , SIGNAL(signalDownloadProcess(qint64, qint64)), this, SLOT(onDownloadProcess(qint64, qint64)));
connect(m_downloadManager, SIGNAL(signalReplyFinished(int)), this, SLOT(onReplyFinished(int)));
}
// 这里先获取到m\_downloadManager中的url与当前的m\_url 对比,如果url变了需要重置参数,防止文件下载不全;
QString url = m_downloadManager->getDownloadUrl();
if (url != m_url)
{
m_downloadManager->reset();
}
m_downloadManager->setDownInto(true);
m_downloadManager->downloadFile(m_url, "F:/MyHttpDownload/MyDownloadFile.zip");
m_timeRecord.start();
m_timeInterval = 0;
ui.labelStatus->setText(QStringLiteral("正在下载"));
}
// 暂停下载;
void MyHttpDownload::onStopDownload()
{
ui.labelStatus->setText(QStringLiteral("停止下载"));
if (m_downloadManager != NULL)
{
m_downloadManager->stopDownload();
}
ui.labelSpeed->setText("0 KB/S");
ui.labelRemainTime->setText("0s");
}
// 关闭下载;
void MyHttpDownload::onCloseDownload()
{
m_downloadManager->closeDownload();
ui.progressBar->setValue(0);
ui.labelSpeed->setText("0 KB/S");
ui.labelRemainTime->setText("0s");
ui.labelStatus->setText(QStringLiteral("关闭下载"));
ui.labelCurrentDownload->setText("0 B");
ui.labelFileSize->setText("0 B");
}
// 更新下载进度;
void MyHttpDownload::onDownloadProcess(qint64 bytesReceived, qint64 bytesTotal)
{
// 输出当前下载进度;
// 用到除法需要注意除0错误;
qDebug() << QString("%1").arg(bytesReceived * 100 / bytesTotal + 1);
// 更新进度条;
ui.progressBar->setMaximum(bytesTotal);
ui.progressBar->setValue(bytesReceived);
// m\_intervalDownload 为下次计算速度之前的下载字节数;
m_intervalDownload += bytesReceived - m_currentDownload;
m_currentDownload = bytesReceived;
![img](https://img-blog.csdnimg.cn/img_convert/9d4bfba736bd370eced756fb342a2ab0.png)
![img](https://img-blog.csdnimg.cn/img_convert/9f1d25bdf73ea16e68c1e611b19834c6.png)
**既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上C C++开发知识点,真正体系化!**
**由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新**
**[如果你需要这些资料,可以戳这里获取](https://bbs.csdn.net/topics/618668825)**
m_currentDownload = bytesReceived;
[外链图片转存中...(img-34X3TpLh-1715661805073)]
[外链图片转存中...(img-UdBbFjXa-1715661805074)]
**既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上C C++开发知识点,真正体系化!**
**由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新**
**[如果你需要这些资料,可以戳这里获取](https://bbs.csdn.net/topics/618668825)**