文章

qt-json

qt-json

本文讲述使用 qt 解析和创建 json 格式。

qt-json

Qt 是一个跨平台 C++ 图形用户界面应用程序开发框架。

下载镜像网址
中国科学技术大学http://mirrors.ustc.edu.cn/qtproject/
清华大学https://mirrors.tuna.tsinghua.edu.cn/qt/

1 介绍

JSON 是一种编码来自 Javascript 的对象数据的格式,但现在已广泛用作互联网上的数据交换格式。 Qt 中的 JSON 支持提供了易于使用的 C++ API 来解析、修改和保存 JSON 数据。

类说明头文件
QJsonDocument读写JSON文档<QtCore/QJsonDocument>
QJsonObject封装JSON对象 { }<QtCore/QJsonObject>
QJsonArray封装JSON数组 [ ]<QtCore/QJsonArray>
QJsonValue封装JSON值 int,float,double,bool,{ },[ ]等<QtCore/QJsonValue>
QJsonParseError报告JSON处理过程中出现的错误<QtCore/QJsonParseError>

2 使用

2.1 QtTest.h

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
#ifndef __QTTEST_H__
#define __QTTEST_H__

#include <QtCore/QFile>
#include <QtCore/QByteArray>
#include <QtCore/QJsonDocument>
#include <QtCore/QJsonObject>
#include <QtCore/QJsonArray>

class QT
{
public:
	QT() {};
	~QT() {};

	static void ParseJsonString(QByteArray str)
	{
		QJsonParseError err;
		// 字符串格式化为JSON
		QJsonDocument  rootDoc = QJsonDocument::fromJson(str, &err);
		if (err.error != QJsonParseError::NoError)
		{
			std::cout << "JSON格式错误" << std::endl;
			return;
		}
		QJsonObject rootObj = rootDoc.object();

		// 修改
		rootObj["age"] = 20;

		// 解析
		QString name = rootObj.value("name").toString();
		int age = rootObj.value("age").toInt();
		QJsonObject addr = rootObj.value("addr").toObject();
		QString country = addr.value("country").toString();
		QString address = addr.value("address").toString();
		QJsonArray skills = rootObj.value("skills").toArray();
		skills.replace(2, "C#");
		rootObj["skills"] = skills;

		// 打印
		std::cout << "name  = " << name.toStdString() << std::endl;
		std::cout << "age   = " << age << std::endl;
		std::cout << "addr  = " << country.toStdString() << " " << address.toStdString() << std::endl;
		std::cout << "skills= [";
		for (auto it = skills.begin(); it != skills.end(); it++)
		{
			std::cout << it->toString().toStdString() << ",";
		}
		std::cout << "\b]" << std::endl;
	}

	static void ParseJsonFile()
	{
		// 没有直接解析的,读取文件字符串解析
		QFile file("read.json");
		if (!file.open(QIODevice::ReadOnly))
		{
			std::cout << "JSON文件打开失败" << std::endl;
		}
		QByteArray content = file.readAll();

		QJsonParseError err;
		// 字符串格式化为JSON
		QJsonDocument  rootDoc = QJsonDocument::fromJson(content, &err);
		if (err.error != QJsonParseError::NoError)
		{
			std::cout << "JSON格式错误" << std::endl;
			return;
		}
		QJsonObject rootObj = rootDoc.object();

		// 解析
		QString name = rootObj.value("name").toString();
		int age = rootObj.value("age").toInt();
		QJsonObject addr = rootObj.value("addr").toObject();
		QString country = addr.value("country").toString();
		QString address = addr.value("address").toString();
		QJsonArray skills = rootObj.value("skills").toArray();

		// 打印
		std::cout << "name  = " << name.toStdString() << std::endl;
		std::cout << "age   = " << age << std::endl;
		std::cout << "addr  = " << country.toStdString() << " " << address.toStdString() << std::endl;
		std::cout << "skills= [";
		for (auto it = skills.begin(); it != skills.end(); it++)
		{
			std::cout << it->toString().toStdString() << ",";
		}
		std::cout << "\b]" << std::endl;
	}

	static void CreateJson()
	{
		// 直接插入,没有先后顺序,自动排序
		QJsonObject rootObject;
		rootObject.insert("name", "张三");
		rootObject.insert("age", 18);

		// [] 中括号添加
		QJsonObject addrObject;
		addrObject["country"] = "中国";
		addrObject["address"] = "四川";
		rootObject.insert("addr", addrObject);

		// 添加数组
		QJsonArray skillsArray;
		skillsArray.append("C++");
		skillsArray.append("Java");
		skillsArray.append("Python");
		rootObject.insert("skills", skillsArray);

		// 转字符串
		// 默认缩进型 JsonFormat::Indented
		// 紧凑型 JsonFormat::Compact
		QByteArray jsonStr = QJsonDocument(rootObject).toJson();
		std::cout << jsonStr.toStdString() << std::endl;
	}
};

#endif // __QTTEST_H__

2.2 main.cpp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
#ifdef _WIN32  
#pragma execution_character_set("utf-8")  // 文件编码 utf8
#endif

#include <iostream>

#include "QtTest.h"

std::string str = "{\
		\"name\": \"张三\",\
		\"age\" : 18,\
		\"addr\" : {\
		    \"country\": \"中国\",\
			\"address\" : \"四川\"\
		},\
		\"skills\" : [\"C++\", \"Java\", \"Python\"]\
	}";

int main(int argc, char** argv)
{
	system("chcp 65001");	// 控制台输出 utf8

	QT::ParseJsonString(QByteArray::fromStdString(str));
	QT::ParseJsonFile();
	QT::CreateJson();

	return 0;
}

3 注意事项

  • QJson 有个坑就是对 json 的大小的限制(64MB

C:\Qt\Qt5.14.2\5.14.2\Src\qtbase\src\corelib\serialization\qjson_p.h

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
class Value
{
public:
    // 最大字节
    enum {
        MaxSize = (1<<27) - 1
    };
    union {
        uint _dummy;
        qle_bitfield<0, 3> type;
        qle_bitfield<3, 1> latinOrIntValue;
        qle_bitfield<4, 1> latinKey;
        qle_bitfield<5, 27> value;
        qle_signedbitfield<5, 27> int_value;
    };
    //...
}
本文由作者按照 CC BY 4.0 进行授权