当前位置:   article > 正文

Qt服务应用操作(二)——JSON文件操作_qt json

qt json

引言

在Qt框架中,JSON(JavaScript Object Notation)是一种轻量级的数据交换格式,易于人阅读和编写,同时也易于机器解析和生成。Qt提供了多个类来支持JSON的解析、生成、修改和序列化,使得在Qt应用程序中处理JSON数据变得简单高效。本文将详细介绍如何在Qt中操作JSON文件。

一、JSON基础知识

JSON主要有两种数据结构:JSON对象和JSON数组。

  • JSON对象:由键值对组成,每个键(key)是字符串,值(value)可以是字符串、数字、布尔值、null、JSON数组或JSON对象。对象以花括号{}包裹,键值对之间用逗号,分隔,键与值之间以冒号:分隔。

    1. // 示例一:JSON对象
    2. {
    3. "name": "John Doe",
    4. "age": 30,
    5. "isEmployed": true
    6. }
  • JSON数组:一系列有序的值的集合,其元素可以是任何JSON类型,包括其他数组或对象。数组以方括号[]包裹,元素之间用逗号,分隔。

    1. // 示例二:JSON数组
    2. ["Apple", "Banana", {"id": 1, "color": "Red"}]

二、Qt中处理JSON的关键类

Qt中处理JSON数据主要涉及以下几个类:

  • QJsonDocument:代表整个JSON文档,负责从/向UTF-8文本或Qt内部二进制格式进行序列化与反序列化。
  • QJsonObject:表示JSON对象,封装了键值对的管理。
  • QJsonArray:表示JSON数组,实现了动态大小的值列表。
  • QJsonValue:封装了JSON支持的数据类型,包括字符串、数字、布尔值、null、对象和数组。
  • QJsonParseError:用于报告JSON解析中的错误类型。
  1. // 相关头文件
  2. #include <QFile> // 文件操作
  3. #include <QJsonObject> // JSON对象
  4. #include <QJsonArray> // JSON数组
  5. #include <QJsonDocument> // JSON文档
  6. #include <QJsonParseError> // JSON异常捕捉

三、生成JSON数据

在Qt中,可以通过组合使用上述类来创建复杂的JSON数据结构。以下是一个示例函数,展示如何创建一个包含嵌套对象和数组的JSON对象:

  1. // 生成复杂JSON对象
  2. QJsonObject createJSONObject() {
  3. QJsonObject personObject; // JSON对象
  4. // 方式一:insert()方法
  5. personObject.insert("name","John Doe");
  6. personObject.insert("age", 30);
  7. personObject.insert("isEmployed", true);
  8. QJsonObject addressObject;
  9. // 方式二:赋值
  10. addressObject["street"] = "123 Main St.";
  11. addressObject["city"] = "Anytown";
  12. addressObject["country"] = "USA";
  13. personObject["address"] = addressObject; // 嵌套JSON对象
  14. QJsonArray hobbiesArray; // JSON数组
  15. hobbiesArray.append("Reading");
  16. hobbiesArray.append("Gaming");
  17. personObject["hobbies"] = hobbiesArray; // 嵌套JSON数组
  18. return personObject;
  19. }
  20. // 运行结果在文章末尾

四、解析JSON数据

给定一个JSON字符串,可以使用Qt的类将其解析为相应的对象或数组结构。以下是一个解析JSON字符串的示例:

  1. // 解析JSON对象
  2. QString parseAndPrintJSON(const QString &jsonString) {
  3. QString strtemp; // 解析后的内容
  4. QJsonParseError error; // 返回JSON解析错误的时候,报告错误信息
  5. QJsonDocument document = QJsonDocument::fromJson(jsonString.toUtf8(), &error);
  6. if (error.error != QJsonParseError::NoError) {
  7. qCritical() << "JSON parsing error: " << error.errorString();
  8. return NULL;
  9. }
  10. // 检查保存的值是否是对象
  11. if (document.isObject()) {
  12. QJsonObject object = document.object(); // 将它转换为JSON对象
  13. for (auto it = object.begin(); it != object.end(); ++it) {
  14. const QString key = it.key();
  15. strtemp += "\nKey: " + key;
  16. qDebug() << "Key:" << key;
  17. // 此处可根据自己需求进一步处理
  18. }
  19. }
  20. return strtemp;
  21. }

五、保存JSON数据到文件

要将JSON数据保存到文件中,你可以使用QFileQTextStream(或QDataStream,但通常对于文本数据,QTextStream更合适)。首先,你需要将QJsonDocument对象序列化为QByteArray,然后将其写入文件。

  1. // 保存JSON数据到文件
  2. void saveJsonToFile(const QString &fileName, const QJsonObject &person) {
  3. // 创建JSON文档
  4. QJsonDocument doc(person);
  5. QFile file(fileName);
  6. // 若文件打开失败,异常处理
  7. if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) {
  8. qCritical() << "无法打开"<< fileName << "文件进行写入" ;
  9. return;
  10. }
  11. /*
  12. 若使用QTextStream,需包含头文件"QTextStream"
  13. QTextStream out(&file);
  14. out << doc.toJson(QJsonDocument::Indented);
  15. */
  16. // 这里使用QFile
  17. file.write(doc.toJson(QJsonDocument::Indented)); // 使用缩进格式使其更易于阅读
  18. file.close();
  19. }

在上面示例函数中,我们使用了QJsonDocument::Indented选项来生成格式化的JSON字符串,这使得文件内容更易于人类阅读。然而,如果你关心文件大小或性能,可以选择不使用缩进(即省略QJsonDocument::Indented参数)。

六、从文件读取JSON数据

从文件读取JSON数据是上述保存过程的逆过程,使用QFileQTextStream读取文件内容,然后使用QJsonDocument::fromJson方法解析JSON字符串,。

  1. // 读取文件数据
  2. QString loadJsonFromFile(const QString &fileName) {
  3. QFile file(fileName);
  4. // 若文件打开失败,异常处理
  5. if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
  6. qCritical() << "无法打开"<< fileName << "文件进行读取";
  7. return NULL;
  8. }
  9. /*
  10. 若使用QTextStream,需包含头文件"QTextStream"
  11. QTextStream in(&file);
  12. QString jsonString = in.readAll();
  13. */
  14. QString jsonString = file.readAll(); // 读取全部内容
  15. file.close(); // 关闭文件
  16. return jsonString; // 返回读取内容,注意:此处内容未解析,可以和上述的解析函数结合使用
  17. }

七、代码及运行结果

1. UI测试界面

2. 代码示例

  • qjsonoper.h
  1. #ifndef QJSONOPER_H
  2. #define QJSONOPER_H
  3. #include <QDialog>
  4. QT_BEGIN_NAMESPACE
  5. namespace Ui { class QJsonOper; }
  6. QT_END_NAMESPACE
  7. class QJsonOper : public QDialog
  8. {
  9. Q_OBJECT
  10. public:
  11. QJsonOper(QWidget *parent = nullptr);
  12. ~QJsonOper();
  13. private slots:
  14. void on_wJsonBtn_clicked(); // 将数据信息写入JSON文件槽函数
  15. void on_rJsonBtn_clicked();// 读取JSON文件数据槽函数
  16. private:
  17. Ui::QJsonOper *ui;
  18. };
  19. #endif // QJSONOPER_H
  • qjsonoper.cpp
  1. #include "qjsonoper.h"
  2. #include "ui_qjsonoper.h"
  3. #include <QMessageBox>
  4. #include <QDebug>
  5. #include <QFile> // 文件操作
  6. #include <QJsonObject> // JSON对象
  7. #include <QJsonArray> // JSON数组
  8. #include <QJsonDocument> // JSON文档
  9. #include <QJsonParseError> // JSON异常捕捉
  10. QJsonOper::QJsonOper(QWidget *parent)
  11. : QDialog(parent)
  12. , ui(new Ui::QJsonOper)
  13. {
  14. ui->setupUi(this);
  15. }
  16. QJsonOper::~QJsonOper()
  17. {
  18. delete ui;
  19. }
  20. // 1. 生成复杂JSON对象
  21. QJsonObject createJSONObject() {
  22. QJsonObject personObject; // JSON对象
  23. // 方式一:insert()方法
  24. personObject.insert("name","John Doe");
  25. personObject.insert("age", 30);
  26. personObject.insert("isEmployed", true);
  27. QJsonObject addressObject;
  28. // 方式二:赋值
  29. addressObject["street"] = "123 Main St.";
  30. addressObject["city"] = "Anytown";
  31. addressObject["country"] = "USA";
  32. personObject["address"] = addressObject; // 嵌套JSON对象
  33. QJsonArray hobbiesArray; // JSON数组
  34. hobbiesArray.append("Reading");
  35. hobbiesArray.append("Gaming");
  36. personObject["hobbies"] = hobbiesArray; // 嵌套JSON数组
  37. return personObject;
  38. }
  39. // 2. 解析JSON对象
  40. QString parseAndPrintJSON(const QString &jsonString) {
  41. QString strtemp; // 解析后的内容
  42. QJsonParseError error; // 返回JSON解析错误的时候,报告错误信息
  43. QJsonDocument document = QJsonDocument::fromJson(jsonString.toUtf8(), &error);
  44. if (error.error != QJsonParseError::NoError) {
  45. qCritical() << "JSON parsing error: " << error.errorString();
  46. return NULL;
  47. }
  48. // 检查保存的值是否是对象
  49. if (document.isObject()) {
  50. QJsonObject object = document.object(); // 将它转换为JSON对象
  51. QStringList keys = object.keys(); //得到所有key
  52. /*for (auto it = object.begin(); it != object.end(); ++it) {
  53. const QString key = it.key();
  54. strtemp += "\nKey: " + key;
  55. qDebug() << "Key:" << key;
  56. // 此处可根据自己需求进一步处理
  57. }*/
  58. for (int i = 0; i < keys.size(); i++) // 遍历每一个键值
  59. {
  60. QString key = keys.at(i);
  61. QJsonValue value = object.value(key);
  62. if (value.isBool())
  63. {
  64. strtemp += key + ":" + value.toBool() + "\n";
  65. }
  66. else if (value.isString())
  67. {
  68. strtemp += key + ":" + value.toString() + "\n";
  69. }
  70. else if (value.isDouble())
  71. {
  72. strtemp += key + ":" + value.toDouble() + "\n";
  73. }
  74. else if (value.isArray())
  75. {
  76. strtemp += keys.at(i) + ":" + "\n";
  77. QJsonArray array = value.toArray();
  78. for (int j = 0; j < array.size(); j++)
  79. {
  80. strtemp += " " + array[j].toString() + "\n";
  81. }
  82. }
  83. else if (value.isObject())
  84. {
  85. strtemp += key + ":" + "\n";
  86. QJsonObject subObj = value.toObject();
  87. QStringList subKeys = subObj.keys();
  88. for(int k = 0; k < subKeys.size(); ++k)
  89. {
  90. QJsonValue subValue = subObj.value(subKeys.at(k));
  91. if (subValue.isString())
  92. {
  93. strtemp += " " + subKeys.at(k) + ":" + subValue.toString() + "\n";
  94. }
  95. else if (subValue.isArray())
  96. {
  97. strtemp += subKeys.at(k) + ":" + "\n";
  98. QJsonArray array = subValue.toArray();
  99. for (int m = 0; m < array.size(); m++)
  100. {
  101. strtemp += " " + array[m].toString() + "\n";
  102. }
  103. }
  104. }
  105. }
  106. }
  107. }
  108. return strtemp;
  109. }
  110. // 3. 保存JSON数据到文件
  111. void saveJsonToFile(const QString &fileName, const QJsonObject &person) {
  112. // 创建JSON文档
  113. QJsonDocument doc(person);
  114. QFile file(fileName);
  115. // 若文件打开失败,异常处理
  116. if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) {
  117. qCritical() << "无法打开"<< fileName << "文件进行写入" ;
  118. return;
  119. }
  120. /*
  121. 若使用QTextStream
  122. QTextStream out(&file);
  123. out << doc.toJson(QJsonDocument::Indented);
  124. */
  125. // 这里使用QFile
  126. file.write(doc.toJson(QJsonDocument::Indented)); // 使用缩进格式使其更易于阅读
  127. file.close();
  128. }
  129. // 4. 读取文件数据
  130. QString loadJsonFromFile(const QString &fileName) {
  131. QFile file(fileName);
  132. // 若文件打开失败,异常处理
  133. if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
  134. qCritical() << "无法打开"<< fileName << "文件进行读取";
  135. return NULL;
  136. }
  137. /*
  138. 若使用QTextStream,需包含头文件"QTextStream"
  139. QTextStream in(&file);
  140. QString jsonString = in.readAll();
  141. */
  142. QString jsonString = file.readAll(); // 读取全部内容
  143. file.close(); // 关闭文件
  144. return jsonString; // 返回读取内容,注意:此处内容未解析,可以和上述的解析函数结合使用
  145. }
  146. // 将数据信息写入JSON文件槽函数
  147. void QJsonOper::on_wJsonBtn_clicked()
  148. {
  149. // 生成JSON对象
  150. QJsonObject person = createJSONObject();
  151. // 保存JSON数据到文件
  152. saveJsonToFile("person.json", person);
  153. // 若保存成功,对话框弹出
  154. QMessageBox::information(this,"success", "恭喜你!成功保存JSON数据到文件!");
  155. }
  156. // 读取JSON文件数据槽函数
  157. void QJsonOper::on_rJsonBtn_clicked()
  158. {
  159. QString fileName = "person.json";
  160. // 读取JSON文件数据,注意未解析
  161. QString jsonString = loadJsonFromFile(fileName);
  162. // 解析JSON对象
  163. QString str = parseAndPrintJSON(jsonString);
  164. // 若读取成功,对话框弹出
  165. QMessageBox::information(this,fileName, str, QMessageBox::Yes);
  166. }
  • main.cpp
  1. #include "qjsonoper.h"
  2. #include <QApplication>
  3. int main(int argc, char *argv[])
  4. {
  5. QApplication a(argc, argv);
  6. QJsonOper w;
  7. w.show();
  8. return a.exec();
  9. }

3. 运行结果

  • 点击:写入JSON文件信息

        查看person.json文件:

  • 点击:读取JSON文件信息

八、总结

在Qt中处理JSON数据是一个常见且重要的任务,特别是在需要与Web服务、配置文件或其他基于JSON的数据源进行交互的应用程序中。通过本文的讲解,我们了解了在Qt中处理JSON数据的几个关键步骤,包括生成JSON数据、解析JSON字符串、遍历JSON对象和数组、以及将JSON数据保存到文件和从文件读取JSON数据。

  1. 生成JSON数据
    我们使用QJsonObjectQJsonArray来构建JSON对象和数组。QJsonObject用于存储键值对,而QJsonArray则用于存储值的数组。通过将这些对象组合起来,我们可以构建复杂的JSON结构。

  2. 解析JSON字符串
    使用QJsonDocument::fromJson()方法将JSON格式的字符串解析为QJsonDocument对象。如果解析成功,我们可以进一步将QJsonDocument对象转换为QJsonObjectQJsonArray,以便访问JSON数据。

  3. 遍历JSON对象和数组
    对于QJsonObject,我们可以使用value()方法来访问其键值对。对于QJsonArray,我们可以使用迭代器或索引来遍历其元素。每个元素可以是另一个QJsonObjectQJsonArray或基本数据类型的值。

  4. 保存JSON数据到文件
    QJsonDocument对象转换为QByteArray,然后使用QFileQTextStream(或QDataStream,但通常对于文本数据,QTextStream更合适)将字节数组写入文件。我们可以使用QJsonDocument::toJson()方法,并可选地指定缩进,以生成易于阅读的JSON格式。

  5. 从文件读取JSON数据
    使用QFileQTextStream(或QDataStream)从文件读取JSON字符串,然后使用QJsonDocument::fromJson()方法将其解析为QJsonDocument对象。

  6. 错误处理
    在解析JSON字符串和打开文件时,我们始终应该检查是否发生了错误,并适当地处理它们。例如,如果JSON字符串格式不正确或文件无法打开,我们应该向用户报告错误并可能采取恢复措施。

通过掌握这些基本技能,你可以在Qt应用程序中有效地使用JSON数据,无论是用于配置管理、网络通信还是数据持久化。JSON的灵活性、易用性和普及性使其成为许多现代应用程序中数据交换的首选格式。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/喵喵爱编程/article/detail/1016464
推荐阅读
相关标签
  

闽ICP备14008679号