C++ Qt开发:QNetworkAccessManager网络接口组件
Qt 是一个跨平台C++图形界面开发库,利用Qt可以快速开发跨平台窗体应用程序,在Qt中我们可以通过拖拽的方式将不同组件放到指定的位置,实现图形化开发极大的方便了开发效率,本章将重点介绍如何运用QNetworkAccessManager
组件实现Web网页访问。
QNetworkAccessManager是Qt网络模块中的关键类,用于管理网络访问和请求。作为一个网络请求的调度中心,它为Qt应用程序提供了发送和接收各种类型的网络请求的能力,包括常见的GET、POST、PUT、DELETE等。这个模块的核心功能在于通过处理QNetworkReply
和QNetworkRequest
来实现与网络资源的交互。
通过QNetworkAccessManager
,Qt应用程序能够轻松地与远程服务器通信,获取数据或将数据上传到服务器。这种网络请求的管理不仅是异步的,以确保不会阻塞主线程,还提供了丰富的信号和槽机制,使得开发者可以灵活地处理不同阶段的网络操作。
通常,QNetworkAccessManager
会与QNetworkReply
和QNetworkRequest
一起使用。QNetworkRequest
用于封装和配置网络请求的各种属性,例如URL、请求头等。而QNetworkReply
则代表了对网络请求的响应,包含了请求返回的数据和相关信息。这三者共同协作,为Qt应用程序提供了便捷、灵活且强大的网络通信能力。
1.1 通用API函数
1.1.1 QNetworkAccessManager
要想实现网络通信首先需要新建一个网络访问管理器,以下是QNetworkAccessManager
类中的一些常用函数及其描述:
函数 | 描述 |
---|---|
QNetworkAccessManager(QObject *parent = nullptr) |
构造函数,创建一个QNetworkAccessManager 实例。 |
virtual ~QNetworkAccessManager() |
虚析构函数,释放QNetworkAccessManager 实例。 |
QNetworkReply *get(const QNetworkRequest &request) |
发送GET请求,并返回与请求关联的QNetworkReply 对象。 |
QNetworkReply *post(const QNetworkRequest &request, QIODevice *data) |
发送POST请求,并返回与请求关联的QNetworkReply 对象。 |
QNetworkReply *post(const QNetworkRequest &request, const QByteArray &data) |
发送POST请求,并返回与请求关联的QNetworkReply 对象。 |
QNetworkReply *put(const QNetworkRequest &request, QIODevice *data) |
发送PUT请求,并返回与请求关联的QNetworkReply 对象。 |
QNetworkReply *put(const QNetworkRequest &request, const QByteArray &data) |
发送PUT请求,并返回与请求关联的QNetworkReply 对象。 |
QNetworkReply *deleteResource(const QNetworkRequest &request) |
发送DELETE请求,并返回与请求关联的QNetworkReply 对象。 |
QNetworkReply *head(const QNetworkRequest &request) |
发送HEAD请求,并返回与请求关联的QNetworkReply 对象。 |
QNetworkReply *sendCustomRequest(const QNetworkRequest &request, const QByteArray &verb, QIODevice *data = nullptr) |
发送自定义请求,并返回与请求关联的QNetworkReply 对象。 |
QNetworkReply *sendCustomRequest(const QNetworkRequest &request, const QByteArray &verb, const QByteArray &data) |
发送自定义请求,并返回与请求关联的QNetworkReply 对象。 |
void setConfiguration(const QNetworkConfiguration &config) |
设置网络配置,用于定制网络行为。 |
QNetworkConfiguration configuration() const |
获取当前网络配置。 |
void clearAccessCache() |
清除网络访问缓存。 |
void setCache(QAbstractNetworkCache *cache) |
设置网络缓存。 |
QAbstractNetworkCache *cache() const |
获取当前网络缓存。 |
void setCookieJar(QNetworkCookieJar *cookieJar) |
设置用于管理HTTP cookie的QNetworkCookieJar 。 |
QNetworkCookieJar *cookieJar() const |
获取当前的HTTP cookie管理器。 |
这些函数提供了QNetworkAccessManager
的核心功能,使得开发者能够方便地进行各种类型的网络请求,配置网络参数,并进行相关的网络管理操作。
1.1.2 QNetworkReply
以下是QNetworkReply
类中的一些常用函数及其描述:
函数 | 描述 |
---|---|
QByteArray readAll() const |
读取所有可用的数据,并返回一个QByteArray ,包含从网络回复读取的所有内容。 |
QByteArray peek(int maxSize) const |
查看最多maxSize 字节的可用数据,但不从缓冲区中移除。 |
QByteArray read(int maxSize) |
从网络回复中读取最多maxSize 字节的数据,并将其从缓冲区中移除。 |
QByteArray readLine(int maxSize = 0) |
从网络回复中读取一行数据,最多包含maxSize 字节,并将其从缓冲区中移除。 |
void ignoreSslErrors(const QList<QSslError> &errors = QList<QSslError>()) |
忽略SSL错误,继续处理网络回复。 |
void abort() |
终止网络回复的处理,关闭底层连接。 |
void close() |
关闭网络回复的处理。 |
QUrl url() const |
返回与网络回复相关联的URL。 |
QNetworkRequest request() const |
返回生成此网络回复的网络请求。 |
QNetworkAccessManager *manager() const |
返回与网络回复相关联的QNetworkAccessManager 。 |
bool isFinished() const |
检查网络回复是否已完成。 |
QNetworkReply::NetworkError error() const |
返回网络回复的错误代码。 |
bool hasRawHeader(const QByteArray &headerName) const |
检查网络回复是否包含指定原始头。 |
QList<QByteArray> rawHeaderList() const |
返回网络回复的所有原始头的列表。 |
QByteArray rawHeader(const QByteArray &headerName) const |
返回指定原始头的值。 |
QVariant header(QNetworkRequest::KnownHeaders header) const |
返回指定标准头的值。 |
QList<QByteArray> rawHeaderValues(const QByteArray &headerName) const |
返回指定原始头的所有值。 |
QVariant attribute(QNetworkRequest::Attribute code) const |
返回指定网络请求属性的值。 |
QIODevice *readAllStandardOutput() |
读取标准输出的所有数据,并返回一个QIODevice ,用于访问读取的内容。 |
QIODevice *readAllStandardError() |
读取标准错误的所有数据,并返回一个QIODevice ,用于访问读取的内容。 |
bool isReadable() const |
检查网络回复是否可读取。 |
这些函数提供了对QNetworkReply
实例进行各种操作和查询的方法,包括读取回复数据、处理SSL错误、获取请求信息、检查错误状态等。开发者可以根据具体需求使用这些函数来有效地与网络回复进行交互。
1.1.3 QNetworkRequest
以下是QNetworkRequest
类中的一些常用函数及其描述:
函数 | 描述 |
---|---|
QNetworkRequest(const QUrl &url) |
使用给定的URL构造一个QNetworkRequest 实例。 |
void setUrl(const QUrl &url) |
设置QNetworkRequest 的URL。 |
QUrl url() const |
返回与QNetworkRequest 相关联的URL。 |
void setRawHeader(const QByteArray &headerName, const QByteArray &headerValue) |
设置指定原始头的值。 |
QByteArray rawHeader(const QByteArray &headerName) const |
返回指定原始头的值。 |
bool hasRawHeader(const QByteArray &headerName) const |
检查QNetworkRequest 是否包含指定原始头。 |
void setRawHeaderList(const QList<QByteArray> &headerList) |
设置所有原始头的列表。 |
QList<QByteArray> rawHeaderList() const |
返回QNetworkRequest 的所有原始头的列表。 |
void setHeader(QNetworkRequest::KnownHeaders header, const QVariant &value) |
设置指定标准头的值。 |
QVariant header(QNetworkRequest::KnownHeaders header) const |
返回指定标准头的值。 |
void setAttribute(QNetworkRequest::Attribute code, const QVariant &value) |
设置指定网络请求属性的值。 |
QVariant attribute(QNetworkRequest::Attribute code) const |
返回指定网络请求属性的值。 |
void setSslConfiguration(const QSslConfiguration &config) |
设置SSL配置。 |
QSslConfiguration sslConfiguration() const |
返回SSL配置。 |
void setMaximumRedirectsAllowed(int maxRedirects) |
设置允许的最大重定向次数。 |
int maximumRedirectsAllowed() const |
返回允许的最大重定向次数。 |
void setOriginatingObject(QObject *object) |
设置发起此网络请求的对象。 |
QObject *originatingObject() const |
返回发起此网络请求的对象。 |
bool isEmpty() const |
检查QNetworkRequest 是否为空(未设置URL)。 |
这些函数提供了对QNetworkRequest
实例进行各种操作和查询的方法,包括设置和获取头信息、设置SSL配置、设置和获取网络请求属性等。开发者可以根据具体需求使用这些函数来有效地构建和管理网络请求。
1.2 实现Web页面访问
要使用该模块读者应该在*.pro
文件内包含network
网络模块,并在头文件中引入QNetworkAccessManager
、QNetworkReply
、QNetworkRequest
三个类,在建立访问时首先使用QNetworkAccessManager
新增一个manager
管理类,并通过QNetworkRequest
类创建一个GET请求地址,通过使用manager.get
方法实现对特定页面的访问。
当访问完成时需要通过一个信号来实现对数据的处理,在QNetworkReply
类中包含有如下表所示的信号以供读者使用,例如当访问被完成时则自动触发&QNetworkReply::finished
完成信号,此时只需要对该信号进行相应的处理即可,通常会使用一个槽函数来处理它。
信号 | 描述 |
---|---|
finished() |
当网络请求完成时发出。 |
downloadProgress(qint64, qint64) |
在下载过程中定期发出,提供下载进度信息。参数为已下载的字节数和总字节数。 |
uploadProgress(qint64, qint64) |
在上传过程中定期发出,提供上传进度信息。参数为已上传的字节数和总字节数。 |
readyRead() |
当有可读取的数据时发出,用于通知应用程序可以调用readAll() 或read() 方法以获取更多数据。 |
error(QNetworkReply::NetworkError) |
当网络请求发生错误时发出,参数为错误代码。 |
sslErrors(const QList<QSslError> &) |
当SSL错误发生时发出,参数为SSL错误的列表。 |
这些信号提供了丰富的信息,使开发者能够在不同阶段处理网络请求。同理,在下载和上传过程中可以使用downloadProgress
和uploadProgress
信号来获取进度信息,readyRead
信号表示有可读取的数据,error
信号表示请求发生错误,sslErrors
信号表示SSL
相关的错误。
当信号被触发时则会通过QObject::connect
连接到对应的槽函数上,如下案例中所示,在槽函数内通过reply->attribute
方法我们获取到此次响应码中的QNetworkRequest::HttpStatusCodeAttribute
属性,该属性用来指明本次访问的状态值。此类属性也有许多可供参考,如下所示;
属性 | 描述 |
---|---|
QNetworkRequest::HttpStatusCodeAttribute |
HTTP响应的状态码。 |
QNetworkRequest::HttpReasonPhraseAttribute |
HTTP响应的原因短语,如"OK"、"Not Found"等。 |
QNetworkRequest::RedirectionTargetAttribute |
重定向目标的URL。 |
QNetworkRequest::ConnectionEncryptedAttribute |
连接是否加密的标志,返回一个bool 值。 |
QNetworkRequest::SourceIsFromCacheAttribute |
请求是否来自缓存的标志,返回一个bool 值。 |
QNetworkRequest::HttpPipeliningAllowedAttribute |
是否允许HTTP流水线传输的标志,返回一个bool 值。 |
QNetworkRequest::HttpPipeliningWasUsedAttribute |
是否使用了HTTP流水线传输的标志,返回一个bool 值。 |
QNetworkRequest::CustomVerbAttribute |
自定义请求动作(HTTP verb)的字符串。 |
QNetworkRequest::User |
用户自定义的属性,用于存储任意类型的用户数据。 |
这些属性提供了额外的信息,使得开发者能够更全面地了解和处理网络响应。根据具体的应用需求,开发者可以选择使用这些属性中的一个或多个来获取所需的信息。
#include <QCoreApplication>
#include <QNetworkAccessManager>
#include <QNetworkReply>
#include <QNetworkRequest>
#include <QDebug>
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
// 创建网络访问管理器
QNetworkAccessManager manager;
// 创建GET请求
QNetworkRequest request(QUrl("http://www.baidu.com"));
// 发送GET请求
QNetworkReply *reply = manager.get(request);
// 连接信号槽,处理响应
QObject::connect(reply, &QNetworkReply::finished, [&]()
{
if (reply->error() == QNetworkReply::NoError)
{
// 获取请求的 URL
qDebug() << "Request URL:" << reply->request().url();
// 输出请求头信息
qDebug() << "Request Headers:";
QList<QByteArray> requestHeaders = reply->request().rawHeaderList();
foreach (const QByteArray &header, requestHeaders) {
qDebug() << header << ":" << reply->request().rawHeader(header);
}
// 获取响应码
int statusCode = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
qDebug() << "HttpStatusCodeAttribute:" << statusCode;
// 连接是否加密的标志
bool connectionEncryptedAttribute = reply->attribute(QNetworkRequest::ConnectionEncryptedAttribute).toBool();
qDebug() << "ConnectionEncryptedAttribute:" << connectionEncryptedAttribute;
// 请求是否来自缓存的标志
bool sourceIsFromCacheAttribute = reply->attribute(QNetworkRequest::SourceIsFromCacheAttribute).toBool();
qDebug() << "SourceIsFromCacheAttribute:" << sourceIsFromCacheAttribute;
// HTTP请求是否被允许进行流水线处理的标志
bool httpPipeliningAllowedAttribute = reply->attribute(QNetworkRequest::HttpPipeliningAllowedAttribute).toBool();
qDebug() << "HttpPipeliningAllowedAttribute:" << httpPipeliningAllowedAttribute;
// 输出响应头信息
qDebug() << "Response Headers:";
QList<QByteArray> responseHeaders = reply->rawHeaderList();
foreach (const QByteArray &header, responseHeaders) {
qDebug() << header << ":" << reply->rawHeader(header);
}
// 处理响应内容,这里可以使用 readAll() 方法获取响应内容
// qDebug() << "Response Content:" << reply->readAll();
} else
{
qDebug() << "Error:" << reply->errorString();
}
// 释放资源
reply->deleteLater();
QCoreApplication::quit();
});
return a.exec();
}
读者可自行编译并运行这段代码,观察请求与相应数据如下图所示;
至于如何在图形界面中使用则就更简单了,首先我们在mainwindow.h
头文件中定义好所需要的两个槽函数,函数on_finished()
用于在完成请求后被调用,函数on_readyRead()
则用于在回调被执行后调用,并并以两个网络管理类的指针变量,如下所示;
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = nullptr);
~MainWindow();
private slots:
//自定义槽函数
void on_finished();
void on_readyRead();
void on_pushButton_clicked();
private:
Ui::MainWindow *ui;
QNetworkAccessManager networkManager; // 网络管理
QNetworkReply *reply; // 网络响应
};
当获取按钮被点击后则开始执行读入指定URL地址,并对该地址进行网页访问,同时绑定这两个信号,一旦被触发则自动路由到对应的槽函数上面去,如下所示;
void MainWindow::on_pushButton_clicked()
{
// 读入URL地址
QString urlSpec = ui->lineEdit->text().trimmed();
if (urlSpec.isEmpty())
{
QMessageBox::information(this, "错误", "请指定URL");
return;
}
// 格式化URL
QUrl newUrl = QUrl::fromUserInput(urlSpec);
if (!newUrl.isValid())
{
QMessageBox::information(this, "错误", QString("无效URL: %1").arg(urlSpec));
return;
}
// 访问页面
reply = networkManager.get(QNetworkRequest(newUrl));
// 完成时的槽函数绑定
connect(reply, SIGNAL(finished()), this, SLOT(on_finished()));
// 读入数据的槽函数绑定
connect(reply, SIGNAL(readyRead()), this, SLOT(on_readyRead()));
}
相对应的,在on_finished()
槽函数中我们将响应头读出并输出到文本框中,在on_readyRead()
槽函数中则是对整个网站页面源代码的输出功能,完整代码如下所示;
void MainWindow::on_finished()
{
// 获取响应码
int statusCode = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
if(statusCode == 200)
{
ui->plainTextEdit_2->appendPlainText("响应头数据:");
// 输出响应头信息
QList<QByteArray> responseHeaders = reply->rawHeaderList();
foreach (const QByteArray &header, responseHeaders)
{
ui->plainTextEdit_2->appendPlainText(header + " : " + reply->rawHeader(header));
}
}
}
// 读入页面源代码
void MainWindow::on_readyRead()
{
ui->plainTextEdit->setPlainText(reply->readAll());
}
运行代码,读者可自行输入特定的网站进行读取测试,如下所示(完整代码请参考课件部分);
C++ Qt开发:QNetworkAccessManager网络接口组件的更多相关文章
- win使用MSYS2安装Qt开发环境
原文链接 MSYS2 下载地址: pacman的具体用法 有pacman的具体使用方法.我们首先对系统升级 我们首先对系统升级 pacman -Syu 就会检测整个系统可以升级的组件,并自动下载安装, ...
- 基于QT开发的第三方库
基于Qt开发的第三方库 分类: Qt2014-02-12 11:34 1738人阅读 评论(0) 收藏 举报 QT第三方库 目录(?)[+] 文章来源:http://blog.csdn.net ...
- 【应用笔记】【AN005】Qt开发环境下基于RS485的4-20mA电流采集
简介 4-20mA电流环具有广泛的应用前景,在许多行业中都发挥着重要作用.本文主要介绍在Qt开发环境下基于RS485实现4-20mA电流采集,实现WINDOWS平台对数据的采集.分析及显示. 系统组成 ...
- 利用Qt开发跨平台APP
本文将手把手教你如何在Windows环境下,使用Qt编译出安卓应用程序. Qt是一个优秀的跨平台开发工具.我们利用Qt可以很方便地将一次编写的应用,多次编译到不同平台上,如Windows.Linux. ...
- Qt开发环境下载和安装
Qt是跨平台的图形开发库,目前由Digia全资子公司 Qt Company 独立运营,官方网址: http://www.qt.io/ 也可以访问Qt项目域名:http://qt-project.org ...
- Qt开发北斗定位系统融合百度地图API及Qt程序打包发布
Qt开发北斗定位系统融合百度地图API及Qt程序打包发布 1.上位机介绍 最近有个接了一个小型项目,内容很简单,就是解析北斗GPS的串口数据然后输出经纬度,但接过来觉得太简单,就发挥了主观能动性,增加 ...
- CAD控件:QT开发使用控件入门
1. 环境搭建: 3 1.1. 安装Qt 3 1.2. 安装Microsoft Windows SDK的调试包 6 2. QT中使用MxDraw控件 7 1.3. 引入控件 7 3. 打开DWG文件 ...
- QT开发环境的建立以及QTE4.6.3、tslib1.4的移植过程
1.首先是建立Linux开发环境1.1.在windowsXP下安装博创公司提供的虚拟机软件VMware Workstation,版本为VMware-workstation-full-7.0.1-227 ...
- 基于arm的嵌入式QT开发(课程设计)
一. 项目要求 配置QT5.7基于x86及arm 等两种CPU架构的调试及开发环境: 移植arm编译后的QT5.7及屏幕校准工具tslib1.4至CORTEX ARM9实验平台: 开发基于QT5.7的 ...
- 关于 Windows 下 Qt 开发,这个问题必须要搞清楚!
小伙伴们,大家好,小北师兄又来喂饭啦,从上次写完<一个例子让你秒懂 Qt Creator 编译原理>后,师兄对于 Qt 的一些环境配置有了更深的理解,这对师兄进行 Qt 的后续学习起到了很 ...
随机推荐
- 一些提供办公效率的软件(clover、f.lux、幕布),老赞了!
1.clover 链接:http://cn.ejie.me/ Clover是由异次元的读者ejie团队开发的一款电脑窗口标签化工具.Clover是电脑中资源管理器的一个扩展程序,可以为其增加多标签页的 ...
- Vulkan学习苦旅01:最初的相遇(学习路线、参考资料与环境配置)
提示:博主本人也在努力学习Vulkan中,文中可能有写错的地方,敬请大家批评指正. 这个世界只有两种人:会Vulkan的和不会Vulkan的,大概不存在"只会一点"的中间状态.学习 ...
- 一句话总结Docker与K8S的关系
一句话总结:Docker只是容器的一种,它面向的是单体,K8S可以管理多种容器,它面向的是集群,Docker可以作为一种容器方案被K8S管理.下文继续具体介绍. 1.容器的核心概念 介绍这几个核心概念 ...
- 高精度模板 大数乘以小数 vector实现
vector<int> Mul(vector<int>& A, int &B) { vector<int>C; int T = 0; for (in ...
- 如何在Delphi TImageList 中使用 透明 png 图标
Query: "Embarcadero Delphi ImageList does not show transparent PNG icons correctly. How to fix ...
- 《ASP.ENT Core 与 RESTful API 开发实战》-- 读书笔记(第1章)
第 1 章 REST 简介 1.1 API 与 REST API 是一个系统向外暴露或公开的一套接口,通过这些接口,外部应用程序能够访问该系统 REST 是一种基于资源的架构风格,任何能够命名的对象都 ...
- Java连接MySQL8.0样例代码
代码功能: 针对MySQL8.0,可以动态传入数据库连接信息(IP.端口.数据库.用户.密码).以及需要执行查询SQL. 注意:由于代码中打印表中的数据,所以最后在Main方法传入的参数是需要是查询的 ...
- [pwn之路]patchelf之后,加载符号表!
# 前言 当你在进行二进制漏洞学习和利用时,经常需要使用调试工具来分析和理解程序的内部工作.在之前的交流中,我们提到了如何使用patchelf来修改二进制文件[Pwn之路]根据所给库,获得远程同环境- ...
- SP9494 ZSUM - Just Add It 题解
题目传送门 前置知识 快速幂 解法 推式子: \(\begin{aligned} Z_n+Z_{n-1}-2Z_{n-2}&=(Z_n-Z_{n-2})+(Z_{n-1}-Z_{n-2}) \ ...
- .net core微服务之网关
网关: 一:apisix doc:https://apisix.apache.org/zh/docs/apisix/getting-started/README/ github:https://git ...