前言
之前只写过通过http协议通信,没有写过下载http地址中的文件或者文件夹,了解一下在QT下如何下载。
其实很简单,同使用协议通信相同的是,创建QNetworkAccessManager和QNetworkRequest,设置QNetworkRequest的url,通过get请求接收QNetworkReply中数据,利用downloadProgress信号接收每次下载下来的内容,直到下载完成。
代码如下:
.pro
主要是加上network模块
#-------------------------------------------------
#
# Project created by QtCreator 2023-10-26T18:29:32
#
#-------------------------------------------------
QT += core gui network
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
TARGET = load_http_file
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
SOURCES += \
main.cpp \
widget.cpp \
HEADERS += \
widget.h \
FORMS += \
widget.ui
界面:
widget.h
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
#include <QFile>
#include <QUrl>
#include <QNetworkReply>
#include <QNetworkRequest>
#include <QNetworkAccessManager>
#include <QEventLoop>
#include <QTimer>
namespace Ui {
class Widget;
}
class Widget : public QWidget
{
Q_OBJECT
public:
explicit Widget(QWidget *parent = 0);
~Widget();
bool downloadFile(QString url);
private slots:
void on_load_zip_clicked();
private:
Ui::Widget *ui;
private:
bool flag_download = false;
};
#endif // WIDGET_H
widget.cpp
#include "widget.h"
#include <QDir>
#include <QThread>
Widget::Widget(QWidget *parent) :
QWidget(parent),
ui(new Ui::Widget)
{
}
Widget::~Widget()
{
delete ui;
}
void Widget::on_load_zip_clicked()
{
downloadFile(ui->lineEdit_url->text());
}
bool Widget::downloadFile(QString url)
{
if(flag_download)
{
qDebug()<<"有正在下载中的文件,已停止当前下载。";
return false;
}
int timeout = 1000 * 60; //* 3;
QString path = "3D";
QDir dir(path);
if(!dir.exists())
{
if(!dir.mkdir(dir.absolutePath()))
{
qDebug()<<"创建3D文件夹失败!";
return false;
}
}
path = path + "/" + url.section('/',-1,-1);
qDebug()<<"url:"<<url<<" path:"<<path;
QFile file(path);
if (!file.open(QIODevice::WriteOnly))
{
qDebug()<<"打开待下载文件失败!";
return false;
}
flag_download = true;
QNetworkAccessManager networkManager;
QNetworkRequest request;
request.setUrl(QUrl(url));
QNetworkReply *reply = networkManager.get(request);
QTimer timer;
QEventLoop eventLoop;
connect(reply, &QNetworkReply::downloadProgress, [=, &file, &timer](qint64 bytesReceived,qint64 bytesTotal){
qDebug()<<"当前下载的文件大小:"<<bytesReceived<<" 总文件大小:"<<bytesTotal;
if (timer.isActive())
timer.start(timeout);
file.write(reply->readAll());
});
connect(reply, &QNetworkReply::finished, &timer, &QTimer::stop);
connect(reply, &QNetworkReply::finished, &eventLoop, &QEventLoop::quit);
connect(&timer, &QTimer::timeout, &eventLoop, &QEventLoop::quit);
timer.start(timeout);
eventLoop.exec();//QEventLoop::ExcludeUserInputEvents
flag_download = false;
if (reply->error() != QNetworkReply::NoError)
{
qDebug()<<"请求失败!失败原因:"<<reply->error();
file.close();
delete reply;
return false;
}
if(timer.isActive())
{
qDebug()<<"请求超时!";
timer.stop();
file.close();
delete reply;
return false;
}
qDebug()<<"下载3D文件成功!";
file.close();
delete reply;
return true;
}