Qt中如何使用JSON文件:从基础到实践
在Qt开发中,JSON(JavaScript Object Notation)作为一种轻量级的数据交换格式,因其结构简洁、可读性强,被广泛应用于配置文件存储、数据序列化、网络通信等场景,Qt提供了强大的QJson模块(Qt5及以后版本推荐使用QJsonDocument、QJsonObject、QJsonArray等类),方便开发者高效地读写JSON文件,本文将详细介绍Qt中操作JSON文件的方法,包括JSON数据的解析、生成、读写及常见问题处理。
Qt JSON模块核心类简介
在开始操作JSON文件前,需先了解Qt中与JSON处理相关的核心类,这些类位于QtJson模块中(需在.pro文件中添加QT += core json):
| 类名 | 作用 |
|---|---|
QJsonDocument |
封装完整的JSON文档,支持将JSON数据转换为字节流或从字节流解析,可包含对象或数组 |
QJsonObject |
表示JSON对象,键(key)为字符串,值(value)为QJsonValue类型 |
QJsonArray |
表示JSON数组,元素为QJsonValue类型,可嵌套对象或数组 |
QJsonValue |
表示JSON中的值,支持基本类型(字符串、数字、布尔值、null)及对象/数组引用 |
QJsonParseError |
用于JSON解析时的错误信息返回,可定位错误位置及类型 |
读取并解析JSON文件
读取JSON文件的核心流程是:读取文件内容 → 解析为QJsonDocument → 提取数据,以下是详细步骤及代码示例。
准备JSON文件
假设有一个名为config.json的配置文件,内容如下:
{
"user": {
"name": "张三",
"age": 25,
"isStudent": false
},
"hobbies": ["编程", "阅读", "旅行"],
"version": 1.0,
"description": null
}
读取文件并解析JSON
使用QFile读取文件内容,通过QJsonDocument::fromJson()解析为JSON文档,再用QJsonObject和QJsonArray提取数据:
#include <QFile>
#include <QJsonDocument>
#include <QJsonObject>
#include <QJsonArray>
#include <QDebug>
void readJsonFile(const QString &filePath) {
// 1. 打开文件
QFile file(filePath);
if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
qWarning() << "无法打开文件:" << file.errorString();
return;
}
// 2. 读取文件内容为字节数组
QByteArray jsonData = file.readAll();
file.close();
// 3. 解析JSON文档
QJsonParseError parseError;
QJsonDocument doc = QJsonDocument::fromJson(jsonData, &parseError);
if (parseError.error != QJsonParseError::NoError) {
qWarning() << "JSON解析错误:" << parseError.errorString() << "位置:" << parseError.offset;
return;
}
// 4. 检查JSON是否为对象(本例为对象,也可能是数组)
if (!doc.isObject()) {
qWarning() << "JSON文档不是对象格式";
return;
}
// 5. 提取数据
QJsonObject jsonObj = doc.object();
// 提取嵌套对象(user对象)
if (jsonObj.contains("user") && jsonObj["user"].isObject()) {
QJsonObject userObj = jsonObj["user"].toObject();
QString name = userObj["name"].toString(); // 张三
int age = userObj["age"].toInt(); // 25
bool isStudent = userObj["isStudent"].toBool(); // false
qDebug() << "用户信息:" << name << age << isStudent;
}
// 提取数组(hobbies数组)
if (jsonObj.contains("hobbies") && jsonObj["hobbies"].isArray()) {
QJsonArray hobbiesArray = jsonObj["hobbies"].toArray();
qDebug() << "爱好列表:";
for (const auto &value : hobbiesArray) {
qDebug() << " -" << value.toString(); // 逐个输出编程、阅读、旅行
}
}
// 提取基本类型
double version = jsonObj["version"].toDouble(); // 1.0
QString description = jsonObj["description"].toString(); // ""(null转为空字符串)
qDebug() << "版本:" << version << "描述:" << description;
}
处理JSON数组
如果JSON文件是数组格式(如data.json:[{"id":1, "name":"A"}, {"id":2, "name":"B"}]),解析时需判断QJsonDocument是否为数组:
void readJsonArrayFile(const QString &filePath) {
QFile file(filePath);
if (!file.open(QIODevice::ReadOnly)) {
qWarning() << "打开文件失败";
return;
}
QJsonDocument doc = QJsonDocument::fromJson(file.readAll());
file.close();
if (!doc.isArray()) {
qWarning() << "JSON文档不是数组";
return;
}
QJsonArray array = doc.array();
for (const auto &value : array) {
if (value.isObject()) {
QJsonObject obj = value.toObject();
qDebug() << "ID:" << obj["id"].toInt() << "名称:" << obj["name"].toString();
}
}
}
生成JSON数据并写入文件
生成JSON文件的流程是:构建QJsonObject/QJsonArray → 封装为QJsonDocument → 写入文件。
构建JSON数据
以下代码将构建与config.json结构相同的JSON数据:
#include <QJsonObject>
#include <QJsonArray>
#include <QJsonDocument>
#include <QFile>
void generateAndWriteJson(const QString &filePath) {
// 1. 构建嵌套对象(user对象)
QJsonObject userObj;
userObj["name"] = "李四";
userObj["age"] = 30;
userObj["isStudent"] = true;
// 2. 构建数组(hobbies数组)
QJsonArray hobbiesArray;
hobbiesArray.append("游戏");
hobbiesArray.append("音乐");
hobbiesArray.append("运动");
// 3. 构建根JSON对象
QJsonObject rootObj;
rootObj["user"] = userObj;
rootObj["hobbies"] = hobbiesArray;
rootObj["version"] = 2.0;
rootObj["description"] = "用户配置信息";
// 4. 封装为QJsonDocument
QJsonDocument doc(rootObj);
if (!doc.isObject()) {
qWarning() << "文档封装失败";
return;
}
// 5. 写入文件
QFile file(filePath);
if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) {
qWarning() << "无法创建文件:" << file.errorString();
return;
}
// 以紧凑格式写入(无缩进),或使用QJsonDocument::Indented格式化输出
file.write(doc.toJson(QJsonDocument::Indented));
file.close();
qDebug() << "JSON文件写入成功:" << filePath;
}
生成JSON数组
若需生成JSON数组(如写入列表数据),可先构建QJsonArray,再封装为QJsonDocument:
void writeJsonArray(const QString &filePath) {
QJsonArray dataArray;
for (int i = 1; i <= 3; ++i) {
QJsonObject item;
item["id"] = i;
item["value"] = QString("Item%1").arg(i);
dataArray.append(item);
}
QJsonDocument doc(dataArray);
QFile file(filePath);
if (file.open(QIODevice::WriteOnly)) {
file.write(doc.toJson());
file.close();
qDebug() << "JSON数组写入成功";
}
}
常见问题与解决方案
中文乱码问题
JSON文件默认使用UTF-8编码,若写入时编码不匹配,可能导致中文乱码,确保:
- 读取时:
QFile以文本模式(QIODevice::Text)打开,自动处理换行符。 - 写入时:使用
doc.toJson()直接输出UTF-8字节流,避免手动编码转换。
若需指定其他编码(如GBK),可通过QString转码后写入:
QString jsonString = "{\"name\":\"中文\"}";
QByteArray utf8Data = jsonString.toUtf8(); // 转为UTF-8
file.write(utf8Data);
键值不存在时的处理
通过QJsonObject::contains()判断



还没有评论,来说两句吧...