赞
踩
在Qt框架中,JSON(JavaScript Object Notation)是一种轻量级的数据交换格式,易于人阅读和编写,同时也易于机器解析和生成。Qt提供了多个类来支持JSON的解析、生成、修改和序列化,使得在Qt应用程序中处理JSON数据变得简单高效。本文将详细介绍如何在Qt中操作JSON文件。
JSON主要有两种数据结构:JSON对象和JSON数组。
JSON对象:由键值对组成,每个键(key)是字符串,值(value)可以是字符串、数字、布尔值、null、JSON数组或JSON对象。对象以花括号{}
包裹,键值对之间用逗号,
分隔,键与值之间以冒号:
分隔。
- // 示例一:JSON对象
- {
- "name": "John Doe",
- "age": 30,
- "isEmployed": true
- }
JSON数组:一系列有序的值的集合,其元素可以是任何JSON类型,包括其他数组或对象。数组以方括号[]
包裹,元素之间用逗号,
分隔。
- // 示例二:JSON数组
- ["Apple", "Banana", {"id": 1, "color": "Red"}]
Qt中处理JSON数据主要涉及以下几个类:
- // 相关头文件
- #include <QFile> // 文件操作
- #include <QJsonObject> // JSON对象
- #include <QJsonArray> // JSON数组
- #include <QJsonDocument> // JSON文档
- #include <QJsonParseError> // JSON异常捕捉
在Qt中,可以通过组合使用上述类来创建复杂的JSON数据结构。以下是一个示例函数,展示如何创建一个包含嵌套对象和数组的JSON对象:
- // 生成复杂JSON对象
- QJsonObject createJSONObject() {
- QJsonObject personObject; // JSON对象
- // 方式一:insert()方法
- personObject.insert("name","John Doe");
- personObject.insert("age", 30);
- personObject.insert("isEmployed", true);
-
- QJsonObject addressObject;
- // 方式二:赋值
- addressObject["street"] = "123 Main St.";
- addressObject["city"] = "Anytown";
- addressObject["country"] = "USA";
- personObject["address"] = addressObject; // 嵌套JSON对象
-
- QJsonArray hobbiesArray; // JSON数组
- hobbiesArray.append("Reading");
- hobbiesArray.append("Gaming");
- personObject["hobbies"] = hobbiesArray; // 嵌套JSON数组
-
- return personObject;
- }
- // 运行结果在文章末尾

给定一个JSON字符串,可以使用Qt的类将其解析为相应的对象或数组结构。以下是一个解析JSON字符串的示例:
- // 解析JSON对象
- QString parseAndPrintJSON(const QString &jsonString) {
- QString strtemp; // 解析后的内容
- QJsonParseError error; // 返回JSON解析错误的时候,报告错误信息
- QJsonDocument document = QJsonDocument::fromJson(jsonString.toUtf8(), &error);
- if (error.error != QJsonParseError::NoError) {
- qCritical() << "JSON parsing error: " << error.errorString();
- return NULL;
- }
- // 检查保存的值是否是对象
- if (document.isObject()) {
- QJsonObject object = document.object(); // 将它转换为JSON对象
- for (auto it = object.begin(); it != object.end(); ++it) {
- const QString key = it.key();
- strtemp += "\nKey: " + key;
- qDebug() << "Key:" << key;
- // 此处可根据自己需求进一步处理
- }
- }
- return strtemp;
- }

要将JSON数据保存到文件中,你可以使用QFile
和QTextStream
(或QDataStream
,但通常对于文本数据,QTextStream
更合适)。首先,你需要将QJsonDocument
对象序列化为QByteArray
,然后将其写入文件。
- // 保存JSON数据到文件
- void saveJsonToFile(const QString &fileName, const QJsonObject &person) {
- // 创建JSON文档
- QJsonDocument doc(person);
-
- QFile file(fileName);
- // 若文件打开失败,异常处理
- if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) {
- qCritical() << "无法打开"<< fileName << "文件进行写入" ;
- return;
- }
- /*
- 若使用QTextStream,需包含头文件"QTextStream"
- QTextStream out(&file);
- out << doc.toJson(QJsonDocument::Indented);
- */
- // 这里使用QFile
- file.write(doc.toJson(QJsonDocument::Indented)); // 使用缩进格式使其更易于阅读
- file.close();
- }

在上面示例函数中,我们使用了QJsonDocument::Indented
选项来生成格式化的JSON字符串,这使得文件内容更易于人类阅读。然而,如果你关心文件大小或性能,可以选择不使用缩进(即省略QJsonDocument::Indented
参数)。
从文件读取JSON数据是上述保存过程的逆过程,使用QFile
和QTextStream
读取文件内容,然后使用QJsonDocument::fromJson
方法解析JSON字符串,。
- // 读取文件数据
- QString loadJsonFromFile(const QString &fileName) {
- QFile file(fileName);
- // 若文件打开失败,异常处理
- if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
- qCritical() << "无法打开"<< fileName << "文件进行读取";
- return NULL;
- }
-
- /*
- 若使用QTextStream,需包含头文件"QTextStream"
- QTextStream in(&file);
- QString jsonString = in.readAll();
- */
- QString jsonString = file.readAll(); // 读取全部内容
- file.close(); // 关闭文件
-
- return jsonString; // 返回读取内容,注意:此处内容未解析,可以和上述的解析函数结合使用
- }

1. UI测试界面
2. 代码示例
- #ifndef QJSONOPER_H
- #define QJSONOPER_H
-
- #include <QDialog>
-
- QT_BEGIN_NAMESPACE
- namespace Ui { class QJsonOper; }
- QT_END_NAMESPACE
-
- class QJsonOper : public QDialog
- {
- Q_OBJECT
-
- public:
- QJsonOper(QWidget *parent = nullptr);
- ~QJsonOper();
-
-
-
- private slots:
- void on_wJsonBtn_clicked(); // 将数据信息写入JSON文件槽函数
-
- void on_rJsonBtn_clicked();// 读取JSON文件数据槽函数
-
- private:
- Ui::QJsonOper *ui;
- };
- #endif // QJSONOPER_H

- #include "qjsonoper.h"
- #include "ui_qjsonoper.h"
-
- #include <QMessageBox>
- #include <QDebug>
-
- #include <QFile> // 文件操作
-
- #include <QJsonObject> // JSON对象
- #include <QJsonArray> // JSON数组
- #include <QJsonDocument> // JSON文档
- #include <QJsonParseError> // JSON异常捕捉
-
- QJsonOper::QJsonOper(QWidget *parent)
- : QDialog(parent)
- , ui(new Ui::QJsonOper)
- {
- ui->setupUi(this);
- }
-
- QJsonOper::~QJsonOper()
- {
- delete ui;
- }
-
- // 1. 生成复杂JSON对象
- QJsonObject createJSONObject() {
- QJsonObject personObject; // JSON对象
- // 方式一:insert()方法
- personObject.insert("name","John Doe");
- personObject.insert("age", 30);
- personObject.insert("isEmployed", true);
-
- QJsonObject addressObject;
- // 方式二:赋值
- addressObject["street"] = "123 Main St.";
- addressObject["city"] = "Anytown";
- addressObject["country"] = "USA";
- personObject["address"] = addressObject; // 嵌套JSON对象
-
- QJsonArray hobbiesArray; // JSON数组
- hobbiesArray.append("Reading");
- hobbiesArray.append("Gaming");
- personObject["hobbies"] = hobbiesArray; // 嵌套JSON数组
-
- return personObject;
- }
-
- // 2. 解析JSON对象
- QString parseAndPrintJSON(const QString &jsonString) {
- QString strtemp; // 解析后的内容
- QJsonParseError error; // 返回JSON解析错误的时候,报告错误信息
- QJsonDocument document = QJsonDocument::fromJson(jsonString.toUtf8(), &error);
- if (error.error != QJsonParseError::NoError) {
- qCritical() << "JSON parsing error: " << error.errorString();
- return NULL;
- }
- // 检查保存的值是否是对象
- if (document.isObject()) {
- QJsonObject object = document.object(); // 将它转换为JSON对象
- QStringList keys = object.keys(); //得到所有key
- /*for (auto it = object.begin(); it != object.end(); ++it) {
- const QString key = it.key();
- strtemp += "\nKey: " + key;
- qDebug() << "Key:" << key;
- // 此处可根据自己需求进一步处理
- }*/
- for (int i = 0; i < keys.size(); i++) // 遍历每一个键值
- {
- QString key = keys.at(i);
- QJsonValue value = object.value(key);
- if (value.isBool())
- {
- strtemp += key + ":" + value.toBool() + "\n";
- }
- else if (value.isString())
- {
- strtemp += key + ":" + value.toString() + "\n";
- }
- else if (value.isDouble())
- {
- strtemp += key + ":" + value.toDouble() + "\n";
- }
- else if (value.isArray())
- {
- strtemp += keys.at(i) + ":" + "\n";
- QJsonArray array = value.toArray();
- for (int j = 0; j < array.size(); j++)
- {
- strtemp += " " + array[j].toString() + "\n";
- }
- }
- else if (value.isObject())
- {
- strtemp += key + ":" + "\n";
- QJsonObject subObj = value.toObject();
- QStringList subKeys = subObj.keys();
- for(int k = 0; k < subKeys.size(); ++k)
- {
- QJsonValue subValue = subObj.value(subKeys.at(k));
- if (subValue.isString())
- {
- strtemp += " " + subKeys.at(k) + ":" + subValue.toString() + "\n";
- }
-
- else if (subValue.isArray())
- {
- strtemp += subKeys.at(k) + ":" + "\n";
- QJsonArray array = subValue.toArray();
- for (int m = 0; m < array.size(); m++)
- {
- strtemp += " " + array[m].toString() + "\n";
- }
- }
- }
- }
- }
- }
- return strtemp;
- }
-
- // 3. 保存JSON数据到文件
- void saveJsonToFile(const QString &fileName, const QJsonObject &person) {
- // 创建JSON文档
- QJsonDocument doc(person);
-
- QFile file(fileName);
- // 若文件打开失败,异常处理
- if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) {
- qCritical() << "无法打开"<< fileName << "文件进行写入" ;
- return;
- }
- /*
- 若使用QTextStream
- QTextStream out(&file);
- out << doc.toJson(QJsonDocument::Indented);
- */
- // 这里使用QFile
- file.write(doc.toJson(QJsonDocument::Indented)); // 使用缩进格式使其更易于阅读
- file.close();
- }
-
- // 4. 读取文件数据
- QString loadJsonFromFile(const QString &fileName) {
- QFile file(fileName);
- // 若文件打开失败,异常处理
- if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
- qCritical() << "无法打开"<< fileName << "文件进行读取";
- return NULL;
- }
-
- /*
- 若使用QTextStream,需包含头文件"QTextStream"
- QTextStream in(&file);
- QString jsonString = in.readAll();
- */
- QString jsonString = file.readAll(); // 读取全部内容
- file.close(); // 关闭文件
-
- return jsonString; // 返回读取内容,注意:此处内容未解析,可以和上述的解析函数结合使用
- }
-
-
- // 将数据信息写入JSON文件槽函数
- void QJsonOper::on_wJsonBtn_clicked()
- {
- // 生成JSON对象
- QJsonObject person = createJSONObject();
-
- // 保存JSON数据到文件
- saveJsonToFile("person.json", person);
-
- // 若保存成功,对话框弹出
- QMessageBox::information(this,"success", "恭喜你!成功保存JSON数据到文件!");
- }
-
- // 读取JSON文件数据槽函数
- void QJsonOper::on_rJsonBtn_clicked()
- {
- QString fileName = "person.json";
- // 读取JSON文件数据,注意未解析
- QString jsonString = loadJsonFromFile(fileName);
-
- // 解析JSON对象
- QString str = parseAndPrintJSON(jsonString);
-
- // 若读取成功,对话框弹出
- QMessageBox::information(this,fileName, str, QMessageBox::Yes);
- }

- #include "qjsonoper.h"
-
- #include <QApplication>
-
- int main(int argc, char *argv[])
- {
- QApplication a(argc, argv);
- QJsonOper w;
- w.show();
- return a.exec();
- }
3. 运行结果
查看person.json文件:
在Qt中处理JSON数据是一个常见且重要的任务,特别是在需要与Web服务、配置文件或其他基于JSON的数据源进行交互的应用程序中。通过本文的讲解,我们了解了在Qt中处理JSON数据的几个关键步骤,包括生成JSON数据、解析JSON字符串、遍历JSON对象和数组、以及将JSON数据保存到文件和从文件读取JSON数据。
生成JSON数据:
我们使用QJsonObject
和QJsonArray
来构建JSON对象和数组。QJsonObject
用于存储键值对,而QJsonArray
则用于存储值的数组。通过将这些对象组合起来,我们可以构建复杂的JSON结构。
解析JSON字符串:
使用QJsonDocument::fromJson()
方法将JSON格式的字符串解析为QJsonDocument
对象。如果解析成功,我们可以进一步将QJsonDocument
对象转换为QJsonObject
或QJsonArray
,以便访问JSON数据。
遍历JSON对象和数组:
对于QJsonObject
,我们可以使用value()
方法来访问其键值对。对于QJsonArray
,我们可以使用迭代器或索引来遍历其元素。每个元素可以是另一个QJsonObject
、QJsonArray
或基本数据类型的值。
保存JSON数据到文件:
将QJsonDocument
对象转换为QByteArray
,然后使用QFile
和QTextStream
(或QDataStream
,但通常对于文本数据,QTextStream
更合适)将字节数组写入文件。我们可以使用QJsonDocument::toJson()
方法,并可选地指定缩进,以生成易于阅读的JSON格式。
从文件读取JSON数据:
使用QFile
和QTextStream
(或QDataStream
)从文件读取JSON字符串,然后使用QJsonDocument::fromJson()
方法将其解析为QJsonDocument
对象。
错误处理:
在解析JSON字符串和打开文件时,我们始终应该检查是否发生了错误,并适当地处理它们。例如,如果JSON字符串格式不正确或文件无法打开,我们应该向用户报告错误并可能采取恢复措施。
通过掌握这些基本技能,你可以在Qt应用程序中有效地使用JSON数据,无论是用于配置管理、网络通信还是数据持久化。JSON的灵活性、易用性和普及性使其成为许多现代应用程序中数据交换的首选格式。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。