QtHttpEx.pro
#-------------------------------------------------
#
# Project created by QtCreator 2019-12-05T21:58:28
#
#-------------------------------------------------
QT += core gui network
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
TARGET = QtHttpEx
TEMPLATE = app
# The following define makes your compiler emit warnings if you use
# any feature of Qt which has been marked as deprecated (the exact warnings
# depend on your compiler). Please consult the documentation of the
# deprecated API in order to know how to port your code away from it.
DEFINES += QT_DEPRECATED_WARNINGS
# You can also make your code fail to compile if you use deprecated APIs.
# In order to do so, uncomment the following line.
# You can also select to disable deprecated APIs only up to a certain version of Qt.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
CONFIG += c++11
SOURCES += \
main.cpp \
ExHttp.cpp
HEADERS += \
ExHttp.h
FORMS += \
ExHttp.ui
macx {
ICON = images/icon.icns
}
unix:!macx{
# linux only
}
win32 {
RC_ICONS = images/icon.ico
}
# Default rules for deployment.
qnx: target.path = /tmp/$${TARGET}/bin
else: unix:!android: target.path = /opt/$${TARGET}/bin
!isEmpty(target.path): INSTALLS += target
RESOURCES += \
resources.qrc
main.cpp
#include "ExHttp.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
ExHttp w;
w.show();
return a.exec();
}
ExHttp.h
#ifndef EXHTTP_H
#define EXHTTP_H
// QMainWindow类提供了一个主应用程序窗口
#include <QMainWindow>
// QNetworkAccessManager类允许应用程序发送网络请求和接收应答
#include <QNetworkAccessManager>
// QNetworkReply类包含用QNetworkAccessManager发送的请求的数据和报头
#include <QNetworkReply>
// QFile类提供了一个读取和写入文件的接口
#include <QFile>
// QUrl类为处理url提供了一个方便的接口
#include <QUrl>
// QDir类提供对目录结构及其内容的访问
#include <QDir>
namespace Ui {
class ExHttp;
}
class ExHttp : public QMainWindow
{
// Q_OBJECT宏必须出现在类定义的私有部分,声明自己的信号和槽,或者使用Qt的元对象系统提供的其他服务
Q_OBJECT
public:
explicit ExHttp(QWidget *parent = nullptr);
~ExHttp();
// 槽函数定义
private slots:
//下载文件
void on_btnDown_clicked();
//默认的保存路径
void on_btnFile_clicked();
// 当单行文本编辑框变化时触发的槽函数
void on_lineEditUrl_textChanged(const QString &arg1);
// 网络响应结束
void onFinished();
// 读取下载的数据
void onReadyRead();
// 下载进程
void onDownloadProgress(qint64 bytesRea, qint64 totalBytes);
private:
// 定义窗口指针句柄
Ui::ExHttp *ui;
// 网络管理指针句柄
QNetworkAccessManager* m_networkManager;
// 网络响应的指针句柄
QNetworkReply* m_reply;
// 下载保存的临时文件指针句柄
QFile* m_file;
};
#endif // EXHTTP_H
ExHttp.cpp
#include "ExHttp.h"
#include "ui_ExHttp.h"
// QMessageBox类提供了一个模态对话框,用于通知用户或向用户提出问题并接收答案
#include <QMessageBox>
// QDir类提供对目录结构及其内容的访问
#include <QDir>
// QDesktopServices类提供了访问公共桌面服务的方法
#include <QDesktopServices>
// 构造函数
ExHttp::ExHttp(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::ExHttp)
{
ui->setupUi(this);
// 这是窗口标题
setWindowTitle("QNetworkAccessManager 网络管理使用 Http 协议下载");
// QNetworkAccessManager类允许应用程序发送网络请求和接收应答
m_networkManager = new QNetworkAccessManager(this);
// 网络响应的指针句柄
m_reply = nullptr;
// 下载保存的临时文件指针句柄
m_file = nullptr;
}
ExHttp::~ExHttp()
{
delete ui;
}
// 下载文件(当“下载”按钮点击时执行此函数)
void ExHttp::on_btnDown_clicked()
{
// 获取下载的URL地址(去掉字符串的首尾的空格)
QString urlSpec = ui->lineEditUrl->text().trimmed();
// 判断URL是否为空
if (urlSpec.isEmpty()) {
// 提示用户下载地址为空
QMessageBox::information(this, "提示", "下载地址URL为NULL");
// 返回
return;
}
// 如果地址不为空,封装用户输入的url字符为一个URL地址
QUrl url = QUrl::fromUserInput(urlSpec);
// 判断此URL是否有效
if (!url.isValid()) {
// 错误提示
QMessageBox::information(this, "提示", QString("无效URL: %1 \n 错误信息: %2").arg(urlSpec, url.errorString()));
// 返回
return;
}
// 获取保存文件路径
QString dir = ui->lineEditFile->text().trimmed();
// 判断保存文件路径是否有效
if (dir.isEmpty()) {
// 错误提示
QMessageBox::information(this, "提示", "保存地址为空");
// 返回
return;
}
// 拼接:保存地址 + 文件名称
QString fileFileName = dir + url.fileName(); //文件保存地址 + 文件名
// 判断该文件是否存在
if (QFile::exists(fileFileName))
// 如果存在就删除
QFile::remove(fileFileName);
// 创建临时文件
m_file = new QFile(fileFileName);
// 以写模式打开该文件,判断是否打开成功
if (!m_file->open(QIODevice::WriteOnly)) {
// 如果打开失败,错误提示
QMessageBox::information(this, "提示", "打开临时文件错误");
// 返回
return;
}
// 将“下载”按钮设置为不可使用
ui->btnDown->setEnabled(false);
// 发送get网络请求,创建网络响应
m_reply = m_networkManager->get(QNetworkRequest(url));
// 发送 finished() 请求完毕信息,触发 onFinished() 槽函数
// finished() 信号:当应答完成处理时发出此信号。发出此信号后,将不再对应答的数据或元数据进行更新
connect(m_reply, SIGNAL(finished()), this, SLOT(onFinished()));
// 发送 readyRead() 请求完毕信息,触发 onReadyRead() 槽函数
// readyRead() 信号:每当从设备当前读取通道中读取新数据时,该信号就会发出一次。它只会在有新数据可用时再次发出
connect(m_reply, SIGNAL(readyRead()), this, SLOT(onReadyRead()));
// 发送 downloadProgress(qint64,qint64) 请求完毕信息,触发 onDownloadProgress(qint64,qint64) 槽函数
// downloadProgress(qint64,qint64) 信号:发出这个信号是为了指示这个网络请求的下载部分的进度(如果有的话)
connect(m_reply, SIGNAL(downloadProgress(qint64,qint64)), this, SLOT(onDownloadProgress(qint64,qint64)));
}
// 默认的保存路径
void ExHttp::on_btnFile_clicked()
{
// 返回应用程序当前目录的绝对路径
QString currPath = QDir::currentPath();
// 保存目录地址
QDir dir(currPath);
// 创建相关目录
dir.mkdir("temp");
// 将目录显示在单行文本编辑器中
ui->lineEditFile->setText(currPath + "/temp/");
}
// 网络响应结束
void ExHttp::onFinished()
{
// QFileInfo类提供与系统无关的文件信息
QFileInfo fileInfo;
// 设置保存文件路径和文件名称
fileInfo.setFile(m_file->fileName());
// 关闭文件
m_file->close();
// 消除文件资源
delete m_file;
// 将文件资源设置为空
m_file = nullptr;
// 计划删除此对象
m_reply->deleteLater();
// 设置
m_reply = nullptr;
// 勾选了,下载完成之后,打开下载的文件
if (ui->checkBox->isChecked())
// absoluteFilePath() 返回包含文件名的绝对路径。
// 使用默认软件的打开下载的文件
QDesktopServices::openUrl(QUrl::fromLocalFile(fileInfo.absoluteFilePath()));
// 设置“下载”按钮可以使用
ui->btnDown->setEnabled(true);
}
// 读取下载的数据
void ExHttp::onReadyRead()
{
// 将返回的数据进行读取,写入到临时文件中
m_file->write(m_reply->readAll());
}
// 下载进程
void ExHttp::onDownloadProgress(qint64 bytesRea, qint64 totalBytes)
{
// 设置进程最大容量
ui->progressBar->setMaximum(totalBytes);
// 设置进程使用时的容量
ui->progressBar->setValue(bytesRea);
}
// 当单行文本编辑框变化时触发的槽函数
void ExHttp::on_lineEditUrl_textChanged(const QString &arg1)
{
// 设置进度条的最大值
ui->progressBar->setMaximum(100);
// 设置进度条显示的值
ui->progressBar->setValue(0);
}
实例代码
https://www.guangdujs.com/read/qt230729/date-2023.07.29.14.28.28