10-网络与 JSON:请求接口与解析数据¶
目录页:见 Qt 教程目录
目标¶
- 能用 Qt 发送一个最简单的 HTTP GET 请求
- 理解网络请求的本质:异步,结果通过信号回来
- 会用 QJsonDocument/QJsonObject 解析 JSON 字符串
先决知识(可选)¶
- 理解信号与槽(见 04 章)
- 知道“不卡 UI”的基本结论(见 09 章)
1. Qt 的网络是怎么工作的:默认就是异步¶
- 专业名称:Asynchronous I/O(异步 I/O)
- 类比:你点外卖下单后不会一直盯着骑手,你继续做别的;外卖到了会通知你(信号)
- 作用:网络等待时 UI 不卡
- 规则/坑点:请求发出后函数立刻返回;真正结果在 reply 的信号里处理
2. QNetworkAccessManager:网络请求的“总管”¶
- 专业名称:QNetworkAccessManager
- 类比:快递总台,负责发件、收件、分发通知
- 作用:创建请求、收到响应
- 规则/坑点:manager 要有稳定生命周期(通常放在窗口成员里);reply 用完要释放(
deleteLater)
3. 最小 GET 请求:下载一段文本(可运行)¶
这个例子把响应文本显示在窗口里。
#include <QApplication>
#include <QLabel>
#include <QNetworkAccessManager>
#include <QNetworkReply>
#include <QNetworkRequest>
#include <QUrl>
#include <QVBoxLayout>
#include <QWidget>
int main(int argc, char *argv[]) {
QApplication app(argc, argv);
QWidget w;
w.setWindowTitle("Network Demo");
auto *layout = new QVBoxLayout(&w);
auto *label = new QLabel("requesting...");
label->setWordWrap(true);
layout->addWidget(label);
QNetworkAccessManager mgr;
QNetworkRequest req(QUrl("https://httpbin.org/get"));
auto *reply = mgr.get(req);
QObject::connect(reply, &QNetworkReply::finished, &w, [=] {
QByteArray body = reply->readAll();
label->setText(QString::fromUtf8(body));
reply->deleteLater();
});
w.resize(640, 420);
w.show();
return app.exec();
}
你要记住两个点:
- mgr.get(req) 立刻返回 reply
- 真正的结果在 reply->finished 之后取
4. JSON 是什么:结构化的数据“包裹”¶
- 专业名称:JSON(JavaScript Object Notation)
- 类比:带标签的快递箱:每个字段都有名字和值
- 作用:接口返回结构化数据,跨语言好解析
- 规则/坑点:JSON 字符串需要解析才能取字段;字段可能缺失,要做健壮处理
5. 解析 JSON:QJsonDocument/QJsonObject(最小示例)¶
你可以先从“解析一段字符串”练起:
#include <QJsonDocument>
#include <QJsonObject>
#include <QString>
QString parseName() {
QByteArray json = R"({"name":"qtcraft","age":18})";
QJsonParseError err;
QJsonDocument doc = QJsonDocument::fromJson(json, &err);
if (err.error != QJsonParseError::NoError || !doc.isObject()) {
return "parse error";
}
QJsonObject obj = doc.object();
return obj.value("name").toString("unknown");
}
规则/坑点:
- 先判断 parse 是否成功
- 先判断是不是 object
- 取字段时给默认值(例如 toString("unknown"))
6. 把网络和 JSON 串起来:请求 → 解析 → 更新 UI¶
写法顺序(新手推荐):
finished里先拿到body- 解析 JSON
- 把你关心的字段拼成一段可读文本
- 设置到 label / list / table 上
这样做的好处是: - 每一步都能单独打印/检查,出错更容易定位
常见坑¶
-
错误:忘了在工程里链接 Network 模块
结果:编译时报找不到 QNetworkAccessManager
正确:CMake 里把Qt::Network加进链接;qmake 里加QT += network -
错误:reply 用完不释放
结果:内存泄漏(请求越多越明显)
正确:reply->deleteLater() -
错误:假设 JSON 字段一定存在
结果:取到空值、逻辑异常
正确:用默认值,并判断类型(例如是 string 还是 number)
小练习¶
练习 1:请求天气/时间接口并显示关键字段¶
- 题目:请求一个公开接口,显示其中 2~3 个字段
- 输入/输出:窗口上显示字段值
- 约束:必须异步处理,不允许阻塞 UI
- 提示:先用浏览器看接口返回的 JSON 再写解析
- 目标:练“网络 + JSON + UI”
练习 2:错误处理¶
- 题目:把网络断开或改成一个错误 URL,显示“错误原因”
- 输入/输出:提示错误信息
- 约束:不能崩溃
- 提示:看
reply->error()和reply->errorString() - 目标:练健壮性
小结¶
- Qt 网络请求默认异步:请求发出后,结果通过信号回来
- QNetworkAccessManager 管请求;QNetworkReply 带响应
- JSON 用 QJsonDocument 解析,取字段要做默认值和类型判断
下一篇:见 11-综合练习-做一个小型桌面工具