基于Qt的HTTP下载的学习

Qt的HTTP下载:

提示:这里可以添加要学的内容

最近一直在学习Qt,然后买的书是Qt 5.9开发指南,学习到HTTP下载的时候发现书里面的例程运行后怎么也下载不了东西,然后经过研究发现书里面有些东西欠缺,需要自己学习补齐。
UI界面如下:
在这里插入图片描述


具体工程代码

废话先不说直接贴代码!

工程文件

关于工程文件.pro的代码

QT       += core gui
QT       +=network	//由于http是基于互联网的 所以要在工程文件中加入 network 
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets

CONFIG += c++17

# You can make your code fail to compile if it uses deprecated APIs.
# In order to do so, uncomment the following line.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000    # disables all the APIs deprecated before Qt 6.0.0

SOURCES += \
    main.cpp \
    htppmain.cpp

HEADERS += \
    htppmain.h

FORMS += \
    htppmain.ui

# Default rules for deployment.
qnx: target.path = /tmp/$${TARGET}/bin
else: unix:!android: target.path = /opt/$${TARGET}/bin
!isEmpty(target.path): INSTALLS += target
	在工程文件中加入network组件

.h代码

#ifndef HTPPMAIN_H
#define HTPPMAIN_H

#include "qnetworkaccessmanager.h"
#include <QMainWindow>
#include <QFile>
#include <QUrl>
QT_BEGIN_NAMESPACE
namespace Ui { class HtppMain; }
QT_END_NAMESPACE

class HtppMain : public QMainWindow
{
    Q_OBJECT

public:
    HtppMain(QWidget *parent = nullptr);
    ~HtppMain();

private:
    Ui::HtppMain *ui;
    QNetworkAccessManager   networkAccessManager;
    QNetworkReply   *reply;
    QFile   *download;

private slots:
    void on_finished();
    void on_readyRead();
    void on_pushButton_2_clicked();
    void on_pushButton_clicked();
};
#endif // HTPPMAIN_H
QNetworkAccessManager类
 	关于网络API的访问其实是基于QNetworkAccessManager类的,这个类可以保存发送的请求和一些配置,其中还包含了监视网络操作的各种信号。
QFile类
	QFile是一种用于读写文本、二进制文件和资源的I/O的类
QNetworkReply类
	QNetworkReply 类封装了使用 QNetworkAccessManager 发布的请求相关的回复信息。
	QNetworkReply 是 QIODevice的子类,这意味着一旦从对象中读取数据,它就不再由设备保留。因此,如果需要,应用程序有责任保留这些数据。
	每当从网络接收和处理更多数据时, readyRead () 信号被发射。
	downloadProgress () 信号也被发射当接收数据时,但其中包含的字节数可能不表示实际接收字节数。

.cpp文件代码

#include "htppmain.h"
#include "ui_htppmain.h"
#include    <QDir>
#include <QMessageBox>
#include <QNetworkReply>
HtppMain::HtppMain(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::HtppMain)
{
    ui->setupUi(this);
}

HtppMain::~HtppMain()
{
    delete ui;
}

//释放内存
void HtppMain::on_finished()
{
    download->close();
    delete download;
    download = Q_NULLPTR;
    reply->deleteLater(); //
    reply = Q_NULLPTR;
}

//当有新数据时,文件将其写入
void HtppMain::on_readyRead()
{
    download->write(reply->readAll());
}


void HtppMain::on_pushButton_2_clicked()
{
//当按钮按下时,获取程序的当前目录并且显示在UI界面
    QString curPath=QDir::currentPath();
    QString sub="temp";
    ui->lineEdit_2->setText(curPath+'/'+sub+'/');
}


void HtppMain::on_pushButton_clicked()
{
    //文本格式的Url
    QString urlSpec =ui->lineEdit->text().trimmed();
    if(urlSpec.isEmpty()){
        QMessageBox::information(this,"error","请指定需要下载的URL");
        return ;
    }
    //字符串转为Url格式
    QUrl url=QUrl::fromUserInput(urlSpec);
    if(!url.isValid()){
         QMessageBox::information(this,"error","无效地址");
         return ;
    }

    //判断路径是否为空 cleanPath可以使路径更简洁
    QString tempDir=QDir::cleanPath(ui->lineEdit_2->text().trimmed());
    if(tempDir.isEmpty()){
        QMessageBox::information(this,"error","无效路径");
        return;
    }

    //获取文件名字
    QString fileName=url.fileName();

    //判断路径是否为空和指向一个正确路径  并且通过prepend()函数将文件名与路径连接在一起形成一个完整路径
    bool useDirectory = !tempDir.isEmpty() && QFileInfo(tempDir).isDir();
    if(useDirectory)
         fileName.prepend(tempDir+'/');

    //如果路径中存在该文件
    if (QFile::exists(fileName)) {
        //选择覆盖掉文件则执行remove
        if (QMessageBox::question(this, tr("Overwrite Existing File"),
                                  tr("There already exists a file called %1%2."
                                     " Overwrite?")
                                     .arg(fileName,
                                          useDirectory
                                           ? QString()
                                           : QStringLiteral(" in the current directory")),
                                     QMessageBox::Yes | QMessageBox::No,
                                     QMessageBox::No)
            == QMessageBox::No) {
            return;
        }
        QFile::remove(fileName);
    }
	//创建一个路径与名字为fileName的临时文件,并且文件为只写类型
    download=new QFile(fileName);
    if(!download->open(QIODevice::WriteOnly)){
        QMessageBox::information(this,"error","临时文件打开错误");
        return;
    }
	//关联到url网络的请求(我自己这么理解)
    reply = networkAccessManager.get(QNetworkRequest(url));
    connect(reply,&QNetworkReply::finished,this,&HtppMain::on_finished);
    connect(reply,&QIODevice::readyRead,this,&HtppMain::on_readyRead);
}

遇到的问题

在使用HTTP下载文件的过程中会出现ssl错误和下载文件大小一直是0kb的情况,
这种情况是由于Qt缺少相应的动态库文件,qt5.13以下需要在Qt安装目录找ssleay32.dll和libeay32.dll这两个文件
在这里插入图片描述
qt5.13以上版本则需要openssl的库,libssl-1_1.dll和libcrypto-1_1.dll库文件。
文件会在Qt安装目录的tool文件夹的对应编译器文件下,找不到可以搜索一下。

在这里插入图片描述

总结

HTTP下载的关键是Url地址正确并且转换为url格式,然后创建路径正式的文件,通过networkAccessManager获得Url的请求,然后将相关请求关联至自己的事件中,然后将数据写入文件最后释放内存。

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值