Qt5开发从入门到精通——第十篇四节(Qt5 网络与通信—— 网页浏览器与文件下载)

欢迎小伙伴的点评✨✨,相互学习c/c++应用开发。🍳🍳🍳
博主🧑🧑 本着开源的精神交流Qt开发的经验、将持续更新续章,为社区贡献博主自身的开源精神👩‍🚀

前言

本章节会给大家带来Qt5 网络与通信—— 网页浏览器与文件下载实例详解。

一、Qt 网络应用开发初步概述

前两节编程所使用的 QUdpSocket 、 QTcpSocket 和 QTcpServer 类都是网络传输层上的类,它们封装实现的是底层的网络进程通信 (Socket 通信)的功能。而 Qt 网络应用开发则是要在此基础上进一步实现应用型的协议功能。应用层的网络协议(如 HTTP/FTP/SMTP 等)简称为“应用协议”,它们运行在 TCP/UDP 之上如下图所示
在这里插入图片描述
Qt 4 以前的版本提供 QHttp 类用于构建 HTTP 客户端,提供 QFtp 类用千开发 FTP 客户端。
从 Qt 5 开始,已经不再分别提供 QHttp 类、 QFtp 类,应用层的编程使用 QNetworkRequest 、 Q
NetworkReply 和 QNetworkAccessManager 这几个高层次的类,它们提供更加简单和强大的接口。
其中,网络请求由 QNetworkRequest 类来表示,作为与请求有关的信息的统一容器,在创建请求对象时指定的 URL 决定了请求使用的协议,目前支待 HTTP 、 FTP 和本地文件 URLs 的上传和下载; QNetworkAceessManager 类用于协调网络操作,每当创建一个请求后,该类用来调度它,并发送信号以报告进度;而对千网络请求的应答则使用 QNetworkReply 类表示,它会
在请求被完成调度时由 QNetworkAccessManager 类创建。

二、效果实例

在应用程序中输入测试下载地址、注意地址不要有空格存在

http://sqdownb.onlinedown.net/down/WeChatSetup.zip

图一
在这里插入图片描述

三、原码

3.1、工程文件已上传GitHub 命令拉取即可

git clone   https://github.com/dhn111/Qt_TCP.git

mainwindow.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QUrl>
class QFile;
class QNetworkReply;
class QNetworkAccessManager;
namespace Ui {
class MainWindow;
}

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    explicit MainWindow(QWidget *parent = nullptr);
    ~MainWindow();
void startRequest(QUrl url);
private slots:
void replyFinished(QNetworkReply *);

void on_pushButton_clicked();

private:
    Ui::MainWindow *ui;

    QNetworkAccessManager *manager;
    void httpFinished();
    void httpReadyRead();
    void updateDataReadProgress(qint64,qint64);
    QNetworkReply *reply;
    QUrl url;
    QFile *file;
};

#endif // MAINWINDOW_H

main.cpp

#include "mainwindow.h"
#include <QApplication>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    MainWindow w;
    w.show();

    return a.exec();
}

mainwindow.cpp

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QtNetwork>
MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    manager= new QNetworkAccessManager(this);
    connect(manager,SIGNAL(finished(QNetworkReply*)), this
    , SLOT(replyFinished(QNetworkReply*)));
    manager->get(QNetworkRequest(QUrl("http://www.baidu.com")));

    ui->setupUi(this);
    ui->progressBar->hide();
}

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


void MainWindow::replyFinished(QNetworkReply *reply)
{
    QString all = reply->readAll ();
    ui->textBrowser->setText(all);
    reply->deleteLater ();
}

void MainWindow::startRequest(QUrl url)
{
    reply= manager->get(QNetworkRequest(url));
    connect (reply, SIGNAL (readyRead ()), this, SLOT (httpReadyRead ()));
    connect(reply,SIGNAL(downloadProgress(qint64,qint64)),this
    , SLOT(updateDataReadProgress(qint64,qint64)));
    connect (reply, SIGNAL (finished()) , this, SLOT (httpFinished ()));
}


void MainWindow::httpReadyRead()
{
   if(file)file->write (reply->readAll ());

}

void MainWindow::updateDataReadProgress(qint64 bytesRead, qint64 totalBytes)
{
    ui->progressBar->setMaximum(totalBytes);
    ui->progressBar->setValue(bytesRead);
}

void MainWindow::httpFinished ()
{
    ui->progressBar->hide ();
    file->flush();
    file->close();
    reply->deleteLater ();
    reply= 0;
    delete file;
    file = 0;
}



void MainWindow::on_pushButton_clicked()
{
    url = ui->lineEdit->text ();
    QFileInfo info (url.path());
    QString fileName (info. fileName ());
    file = new QFile (fileName);

    if (!file->open(QIODevice::WriteOnly))
    {
        qDebug () <<"file open error";
        delete file;
        file = 0;
        return;
    }
    startRequest(url);
    ui->progressBar->setValue(100);
    ui->progressBar->show();
}

四、原码步骤解析

下面在网页浏览实例的基础上,实现一般页面文件的下载,并且显示下载进度 。 进入设计模式,向界面上拖入 Label、 LineEdit、 ProgressBar 和 PushButton 等部件,最终效果如下图

在这里插入图片描述

新建 Qt Widgets Application, 名称为 "myHTTP ", 类名为 “MainWindow”, 基类保待
“QMainWindow” 不变。完成后在 “myHTTP.pro” 文件中添加语句 “QT+=network”, 并保存该文件。进入设计模式,向界面上拖入一个 Text Browser, 进入 “mainwindow.h” 文件,首先添加
类的前置声明:

class QNetworkReply;
class QNetworkAccessManager;

然后添加一个私有对象定义:

QNetworkAccessManager *manager;

再添加一个私有槽的声明:

private slots:
void replyFinished(QNetworkReply *);

在 “mainwindow.cpp” 文件中,首先添加头文件:

#include <QtNetwork>

然后在构造函数中添加如下代码:

    manager= new QNetworkAccessManager(this);
    connect(manager,SIGNAL(finished(QNetworkReply*)), this
    , SLOT(replyFinished(QNetworkReply*)));
    manager->get(QNetworkRequest(QUrl("http://www.baidu.com")));

这里首先创建了 一个 QNetworkAccessManager 类的实例,它用来发送网络请求和接收应答。然后关联了管理器的 finished()信号和自定义的槽,每当网络应答结束时都会发送这个信号。最后使用了 get()函数来发送一个网络请求,网络请求使用 QNetworkRequest 类表示, get()函数返回 一个 QNetworkReply 对象。
下面添加槽的定义:

void MainWindow::replyFinished(QNetworkReply *reply)
{
    QString all = reply->readAll ();
    ui->textBrowser->setText(all);
    reply->deleteLater ();
}

因为 QNetworkReply 类继承自 QIODevice 类,所以可以像操作一般的 1/0 设备一样操作该类。这里使用了 readAll()函数来读取所有的应答数据。在完成数据的读取后,需要使用 deleteLater()
函数删除 reply 对象。
进行设计下载文件逻辑
首先,在 “mainwindow.h” 文件中添加头文件和类的前置声明:

#include <QUrl>
class QFile;

其次,添加如下私有槽声明:

    void httpFinished();
    void httpReadyRead();
    void updateDataReadProgress(qint64,qint64);
 

再添加一个 publicO函数声 明:

void startRequest(QUrl url);

再次,添加几个私有对象定义:

    QNetworkReply *reply;
    QUrl url;
    QFile *file;

在 “mainwindow.cpp” 文件中,在构造函数中添加:

ui->progressBar->hide();

这里开始将进度条隐藏了,因此在没有下载文件时是不显示进度条的。
接下来添加几个新函数,首先添加网络请求函数的实现:

void MainWindow::startRequest(QUrl url)
{
    reply= manager->get(QNetworkRequest(url));
    connect (reply, SIGNAL (readyRead ()), this, SLOT (httpReadyRead ()));
    connect(reply,SIGNAL(downloadProgress(qint64,qint64)),this
    , SLOT(updateDataReadProgress(qint64,qint64)));
    connect (reply, SIGNAL (finished()) , this, SLOT (httpFinished ()));
}

这里使用了 get()函数发送网络请求,'进行了 QNetworkReply 对象的几个信号和自定义槽的关联。
其中, readyRead()信号继承自 QIODevice 类,每当有新的数据可以读取时,都会发送该信号;每当网络请求的下载进度更新时,都会发送 downloadProgress()信号,用于更新进度条;每当应答处理结束时,都会发送 finishedQ信号,该信号与前面程序中 QNetworkAccessManager 类的 finished()信号作用相同,只不过是发送者不同,参数也不同而已。
下面添加几个槽的定义:

void MainWindow::httpReadyRead()
{
   if(file)file->write (reply->readAll ());

}

这里首先判断是否创建了文件。如果是,则读取返回的所有数据,然后写入文件中。该文
件是在后面的“下载”按钮的单击信号的槽中创建并打开的。

void MainWindow::updateDataReadProgress(qint64 bytesRead, qint64 totalBytes)
{
    ui->progressBar->setMaximum(totalBytes);
    ui->progressBar->setValue(bytesRead);
}

这里设置了进度条的最大值和当前值。

void MainWindow::httpFinished ()
{
    ui->progressBar->hide ();
    file->flush();
    file->close();
    reply->deleteLater ();
    reply= 0;
    delete file;
    file = 0;
}

当完成下载后,重新隐藏进度条,删除 reply 和 file 对象。进入设计模式,进入“下载”按钮的单击信号的槽。

void MainWindow::on_pushButton_clicked()
{
    url = ui->lineEdit->text ();
    QFileInfo info (url.path());
    QString fileName (info. fileName ());
    file = new QFile (fileName);

    if (!file->open(QIODevice::WriteOnly))
    {
        qDebug () <<"file open error";
        delete file;
        file = 0;
        return;
    }
    startRequest(url);
    ui->progressBar->setValue(100);
    ui->progressBar->show();
}

五、总结

Qt5 网络与通信—— 网页浏览器与文件下载会在应用程序开发中经常用到的。

  • 13
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 15
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 15
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

东.'

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值