Qt之http客户端类
一、HTTP客户端类功能:
1、POST请求发送:
- 支持发送JSON格式的数据
- 自动处理请求头设置
- 提供上传进度监控、
2、GET请求发送:
- 简单的GET请求实现
- 支持下载进度监控
3、状态监控:
- 通过信号槽机制监控上传/下载进度
- 错误处理和状态回调
/*** @file HttpClient.h* @brief HTTP客户端类,用于处理HTTP请求* @details 提供异步HTTP请求功能,支持GET和POST方法,包含进度监控和错误处理*/#include <QNetworkAccessManager>
#include <QNetworkRequest>
#include <QNetworkReply>
#include <QJsonDocument>
#include <QJsonObject>
#include <QEventLoop>/*** @class HttpClient* @brief HTTP客户端类,继承自QObject* @details 封装了Qt网络请求功能,提供简单的接口进行HTTP通信*/
class HttpClient : public QObject
{Q_OBJECTpublic:/*** @brief 构造函数* @param parent 父对象指针,用于Qt对象树管理*/explicit HttpClient(QObject *parent = nullptr) : QObject(parent) {manager = new QNetworkAccessManager(this);}/*** @brief 析构函数* @details 清理网络管理器资源*/~HttpClient() {if (manager) {manager->deleteLater();manager = nullptr;}}/*** @brief 发送POST请求* @param url 目标URL地址* @param data 要发送的JSON数据* @param callback 请求完成后的回调函数,参数为(是否成功, 响应内容/错误信息)*/void sendPostRequest(const QString& url, const QJsonObject& data, std::function<void(bool success, const QString& response)> callback) {// 创建网络请求对象QNetworkRequest request(url);// 设置请求头为JSON格式request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");// 将JSON对象转换为字节数组QJsonDocument doc(data);QByteArray postData = doc.toJson();// 发送POST请求QNetworkReply* reply = manager->post(request, postData);// 连接完成信号到响应处理函数connect(reply, &QNetworkReply::finished, this, [=]() {handleResponse(reply, callback);});// 连接上传进度信号connect(reply, &QNetworkReply::uploadProgress, this, &HttpClient::onUploadProgress);// 连接下载进度信号connect(reply, &QNetworkReply::downloadProgress, this,&HttpClient::onDownloadProgress);}/*** @brief 发送GET请求* @param url 目标URL地址* @param callback 请求完成后的回调函数,参数为(是否成功, 响应内容/错误信息)*/void sendGetRequest(const QString& url,std::function<void(bool success, const QString& response)> callback) {QNetworkRequest request(url);QNetworkReply* reply = manager->get(request);connect(reply, &QNetworkReply::finished, this, [=]() {handleResponse(reply, callback);});}signals:/*** @brief 上传进度信号* @param bytesSent 已发送的字节数* @param bytesTotal 总字节数*/void uploadProgressChanged(qint64 bytesSent, qint64 bytesTotal);/*** @brief 下载进度信号* @param bytesReceived 已接收的字节数* @param bytesTotal 总字节数*/void downloadProgressChanged(qint64 bytesReceived, qint64 bytesTotal);private slots:/*** @brief 处理上传进度的槽函数* @param bytesSent 已发送的字节数* @param bytesTotal 总字节数*/void onUploadProgress(qint64 bytesSent, qint64 bytesTotal) {emit uploadProgressChanged(bytesSent, bytesTotal);}/*** @brief 处理下载进度的槽函数* @param bytesReceived 已接收的字节数* @param bytesTotal 总字节数*/void onDownloadProgress(qint64 bytesReceived, qint64 bytesTotal) {emit downloadProgressChanged(bytesReceived, bytesTotal);}private:/** @brief 网络访问管理器指针 */QNetworkAccessManager* manager;/*** @brief 处理网络响应* @param reply 网络响应对象指针* @param callback 回调函数* @details 处理请求完成后的响应数据或错误信息,并调用回调函数*/void handleResponse(QNetworkReply* reply,std::function<void(bool success, const QString& response)> callback) {if (reply->error() == QNetworkReply::NoError) {// 请求成功,读取响应数据QString response = QString::fromUtf8(reply->readAll());callback(true, response);} else {// 请求失败,获取错误信息QString errorString = reply->errorString();callback(false, errorString);}// 清理响应对象reply->deleteLater();}
};
二、使用方式
1、作为类成员变量使用
class MyClass : public QObject {Q_OBJECT
private:HttpClient* httpClient;public:MyClass(QObject* parent = nullptr) : QObject(parent) {httpClient = new HttpClient(this); // 将this作为父对象}// 不需要显式删除,会随父对象自动删除~MyClass() {// httpClient会自动删除,不需要手动删除}
};
2、 作为局部变量使用
void someFunction() {// 在栈上创建HttpClient client;// 使用client发送请求client.sendPostRequest("...", data, [](bool success, const QString& response) {// 处理响应});// client会在函数结束时自动销毁
}
3、动态分配使用
void someFunction() {// 动态创建HttpClient* client = new HttpClient();// 使用client发送请求client->sendPostRequest("...", data, [client](bool success, const QString& response) {// 处理响应// 在回调中删除clientclient->deleteLater();});
}
4、使用智能指针
#include <QScopedPointer>void someFunction() {QScopedPointer<HttpClient> client(new HttpClient());// 使用client发送请求client->sendPostRequest("...", data, [](bool success, const QString& response) {// 处理响应});// client会在QScopedPointer销毁时自动删除
}
三、示例
// 创建客户端实例
HttpClient* client = new HttpClient(this);// 监听进度信号
connect(client, &HttpClient::uploadProgressChanged, this, [](qint64 sent, qint64 total) {qDebug() << "Upload progress:" << sent << "/" << total;
});// 准备POST数据
QJsonObject data;
data["name"] = "test";
data["value"] = 123;// 发送POST请求
client->sendPostRequest("http://api.example.com/endpoint", data, [](bool success, const QString& response) {if (success) {qDebug() << "Response:" << response;} else {qDebug() << "Error:" << response;}}
);
注意事项:
- 如果 HttpClient 作为 QObject 的子对象创建,会随父对象自动删除,不需要手动删除
- 使用 deleteLater() 而不是直接 delete,确保在 Qt 事件循环中安全删除对象
- 如果有正在进行的网络请求,建议等待请求完成后再删除 HttpClient
- 使用智能指针可以避免手动管理内存,推荐使用
相关文章:
Qt之http客户端类
一、HTTP客户端类功能: 1、POST请求发送: 支持发送JSON格式的数据自动处理请求头设置提供上传进度监控、 2、GET请求发送: 简单的GET请求实现支持下载进度监控 3、状态监控: 通过信号槽机制监控上传/下载进度错误处理和状态回调 /…...
18.C语言文件操作详解:指针、打开、读取与写入
目录 1.文件指针2.fopen3.标准流4.fclose5.EOF6.freopen()7.fgetc与getc8. fputc与putc9.fprintf10.fscanf11.fgets12.fputs13.fwrite14.fread15.feof16.fseek17.ftell18.rewind19.fgetpos()与fsetpos20.ferror与clearerr21.remove22.rename 1.文件指针 本篇原文为:…...
深入浅出 OpenResty
1. 引言 1.1. OpenResty简介 OpenResty 是一个基于 Nginx 的高性能 Web 平台,它集成了大量模块,并原生支持 Lua 脚本。这使得开发者能够以非常灵活的方式实现复杂的逻辑,而无需重新编译或扩展 Nginx 核心。OpenResty 的主要特点包括&#x…...

在 .NET 9 中使用 Scalar 替代 Swagger
前言 在.NET 9发布以后ASP.NET Core官方团队发布公告已经将Swashbuckle.AspNetCore(一个为ASP.NET Core API提供Swagger工具的项目)从ASP.NET Core Web API模板中移除,这意味着以后我们创建Web API项目的时候不会再自动生成Swagger API文档了…...

ue5 蒙太奇,即上半身动画和下半身组合在一起,并使用。学习b站库得科技
本文核心 正常跑步动画端枪动画跑起来也端枪 正常跑步动画 端枪动画的上半身 跑起来也端枪 三步走: 第一步制作动画蒙太奇和插槽 第二步动画蓝图选择使用上半身动画还是全身动画,将上半身端枪和下半身走路结合 第三步使用动画蒙太奇 1.开始把&a…...

多活架构的实现原理与应用场景解析
一、多活架构为何如此重要? 企业的业务运营与各类线上服务紧密相连,从日常的购物消费、社交娱乐,到金融交易、在线教育等关键领域,无一不依赖于稳定可靠的信息系统。多活架构的重要性愈发凸显,它宛如一位忠诚的卫士,为业务的平稳运行保驾护航。 回想那些因系统故障引发的…...
一 rk3568 Android 11固件开发环境搭建 (docker)
一 目标 搭建 rk3568 android 系统内核 及固件开发编译调试环境, 支持开发环境导出分享 基于荣品 rk3568 核心板 系统环境: ubuntu22.04 /ubuntu20.04 64位桌面版 编译环境: docker + ubuntu20.04 , 独立的容器隔离环境,不受系统库版本冲突等影响,无性能损耗, 可…...
小结:华为路由器常用的操作指令
以下是华为路由器常用的操作指令(适用于华为企业级路由器,基于VRP操作系统): 1. 基本操作命令 进入用户视图模式 <Huawei> (默认进入用户视图) 进入系统视图模式 <Huawei> system-view [Huawe…...
旅游网站设计与实现
文末附有完整项目代码 在当今数字化时代,旅游网站成为人们获取旅游信息的重要途径。本文将详细介绍旅游网站的设计与实现,让你轻松了解其中的技术奥秘! 一、项目背景 随着社会经济的发展,人们对精神消费愈发重视,旅游…...

【AI大模型】BERT GPT ELMo模型的对比
目录 🍔 BERT, GPT, ELMo之间的不同点 🍔 BERT, GPT, ELMo各自的优点和缺点 🍔 小结 学习目标 理解BERT, GPT, ELMo相互间的不同点理解BERT, GPT, ELMo相互比较下的各自优点和缺点 🍔 BERT, GPT, ELMo之间的不同点 关于特征提取…...

qt 快捷功能 快速生成 setter getter 构造函数 父类虚函数重写 成员函数实现 代码框架 查看父类及父类中的虚函数
qt 快速生成 setter getter 构造函数 父类虚函数重写 成员函数实现 代码框架 1、找到要实现的头文件 2、鼠标移动到在头文件中的类定义的类名上,右键进行选择。 这是插入父类虚函数(父类虚函数重写) 选项弹出来的结果。可以查看到所有父类及父类中的所有的虚函数...

【计算机网络】深入浅出计算机网络
第一章 计算机网络在信息时代的作用 计算机网络已由一种通信基础设施发展成一种重要的信息服务基础设施 CNNIC 中国互联网网络信息中心 因特网概述 网络、互联网和因特网 网络(Network)由若干结点(Node)和连接这些结点的链路…...

springMVC---resultful风格
目录 一、创建项目 pom.xml 二、配置文件 1.web.xml 2.spring-mvc.xml 三、图解 四、controller 一、创建项目 pom.xml <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0"xmlns:xsi…...

汽车基础软件AutoSAR自学攻略(三)-AutoSAR CP分层架构(2)
汽车基础软件AutoSAR自学攻略(三)-AutoSAR CP分层架构(2) 下面我们继续来介绍AutoSAR CP分层架构,下面的文字和图来自AutoSAR官网目前最新的标准R24-11的分层架构手册。该手册详细讲解了AutoSAR分层架构的设计,下面让我们来一起学习一下。 Introductio…...
IntelliJ IDEA 主题插件
在 IntelliJ IDEA 中,有很多优秀的主题插件可以帮助你改变 IDE 的外观和配色方案,使得开发过程更加愉悦和高效。以下是一些非常受欢迎和实用的 主题插件,以及如何安装和使用它们的步骤: 🌟 流行主题插件推荐 1️⃣ Ma…...

2025最新JAVA面试八股文【基础篇】
1、面向对象和面向过程的区别 2、标识符的命名规则 3、Java自动装箱与拆箱 4、 方法重载和方法重写的区别 5、 equals与 的区别 6、 Hashcode的作用 7、 String、StringBuffer 和 StringBuilder 的区别是什么? 8、ArrayList和linkedList的区别 9、 HashMap和HashTabl…...
element plus 使用 el-tree 组件设置默认选中和获取所有选中节点id
1. 设置默认选中: 使用 default-checked-keys 属性,设置默认要选中的节点,以数组形式,如下: <el-treeref"treeRef":data"data"show-checkboxnode-key"id":props"defaultProps…...
高级java每日一道面试题-2025年01月09日-数据库篇-视图是什么?
如果有遗漏,评论区告诉我进行补充 面试官: 视图是什么? 我回答: 在Java高级面试中,当讨论到数据库中的视图(View)时,通常指的是一种虚拟表或逻辑表。视图并不存储实际数据,而是基于SQL查询定义的一种数据表示形式。…...
python学习整理
在cmd界面里 安装python notebook 1.pip install notebook -i https://pypi.tuna.tsinghua.edu.cn/simple 打开 notebook jupyter notebook 更改默认路径 找到配置文件路径: jupyter notebook --generate-config 搜索’notebook_dir 内容进行修改路径&#x…...

Qt 5.14.2 学习记录 —— 십이 QLineEdit、QTextEdit
文章目录 1、QLineEdit1、写程序2、正则表达式检查电话号码3、验证两次输入的密码是否一致4、切换显示密码状态 2、TextEdit1、多行编写2、信号 1、QLineEdit text在代码上改变或者界面上直接改动都会修改这个属性。 clearButtonEnabled,输入框为空,没有…...
[特殊字符] 智能合约中的数据是如何在区块链中保持一致的?
🧠 智能合约中的数据是如何在区块链中保持一致的? 为什么所有区块链节点都能得出相同结果?合约调用这么复杂,状态真能保持一致吗?本篇带你从底层视角理解“状态一致性”的真相。 一、智能合约的数据存储在哪里…...
Android Wi-Fi 连接失败日志分析
1. Android wifi 关键日志总结 (1) Wi-Fi 断开 (CTRL-EVENT-DISCONNECTED reason3) 日志相关部分: 06-05 10:48:40.987 943 943 I wpa_supplicant: wlan0: CTRL-EVENT-DISCONNECTED bssid44:9b:c1:57:a8:90 reason3 locally_generated1解析: CTR…...
Vue记事本应用实现教程
文章目录 1. 项目介绍2. 开发环境准备3. 设计应用界面4. 创建Vue实例和数据模型5. 实现记事本功能5.1 添加新记事项5.2 删除记事项5.3 清空所有记事 6. 添加样式7. 功能扩展:显示创建时间8. 功能扩展:记事项搜索9. 完整代码10. Vue知识点解析10.1 数据绑…...

练习(含atoi的模拟实现,自定义类型等练习)
一、结构体大小的计算及位段 (结构体大小计算及位段 详解请看:自定义类型:结构体进阶-CSDN博客) 1.在32位系统环境,编译选项为4字节对齐,那么sizeof(A)和sizeof(B)是多少? #pragma pack(4)st…...
【SpringBoot】100、SpringBoot中使用自定义注解+AOP实现参数自动解密
在实际项目中,用户注册、登录、修改密码等操作,都涉及到参数传输安全问题。所以我们需要在前端对账户、密码等敏感信息加密传输,在后端接收到数据后能自动解密。 1、引入依赖 <dependency><groupId>org.springframework.boot</groupId><artifactId...

Psychopy音频的使用
Psychopy音频的使用 本文主要解决以下问题: 指定音频引擎与设备;播放音频文件 本文所使用的环境: Python3.10 numpy2.2.6 psychopy2025.1.1 psychtoolbox3.0.19.14 一、音频配置 Psychopy文档链接为Sound - for audio playback — Psy…...
WEB3全栈开发——面试专业技能点P2智能合约开发(Solidity)
一、Solidity合约开发 下面是 Solidity 合约开发 的概念、代码示例及讲解,适合用作学习或写简历项目背景说明。 🧠 一、概念简介:Solidity 合约开发 Solidity 是一种专门为 以太坊(Ethereum)平台编写智能合约的高级编…...
LRU 缓存机制详解与实现(Java版) + 力扣解决
📌 LRU 缓存机制详解与实现(Java版) 一、📖 问题背景 在日常开发中,我们经常会使用 缓存(Cache) 来提升性能。但由于内存有限,缓存不可能无限增长,于是需要策略决定&am…...

Golang——9、反射和文件操作
反射和文件操作 1、反射1.1、reflect.TypeOf()获取任意值的类型对象1.2、reflect.ValueOf()1.3、结构体反射 2、文件操作2.1、os.Open()打开文件2.2、方式一:使用Read()读取文件2.3、方式二:bufio读取文件2.4、方式三:os.ReadFile读取2.5、写…...
日常一水C
多态 言简意赅:就是一个对象面对同一事件时做出的不同反应 而之前的继承中说过,当子类和父类的函数名相同时,会隐藏父类的同名函数转而调用子类的同名函数,如果要调用父类的同名函数,那么就需要对父类进行引用&#…...