欢迎小伙伴的点评✨✨,相互学习c/c++应用开发。
博主 本着开源的精神交流Qt开发的经验、将持续更新续章,为社区贡献博主自身的开源精神
本章节会给大家带来Qt5 网络与通信—— 网页浏览器与文件下载实例详解。
前两节编程所使用的 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
git clone https://github.com/dhn111/Qt_TCP.git
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include
#include
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
#include "mainwindow.h"
#include
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.show();
return a.exec();
}
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include
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
然后在构造函数中添加如下代码:
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
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 网络与通信—— 网页浏览器与文件下载会在应用程序开发中经常用到的。