Qt支持处理JSON数据。JSON是一种对源自Javascript的对象数据进行编码的格式,但现在被广泛用作互联网上的数据交换格式。
Qt中的JSON支持提供了一个易于使用的C++API来解析、修改和保存JSON数据。它还支持以二进制格式保存数据,这种格式可以直接“mmap”,并且访问速度非常快。
JSON数据格式的更多详细信息可以在JSON中找到。
https://www.json.org/json-en.html和RFC-4627
中https://www.rfc-editor.org/rfc/rfc4627
JSON是一种存储结构化数据的格式。它有6种基本数据类型:
bool
double
string
array
object
null
值可以具有上述任何类型。bool由JSON中的字符串true或false表示。JSON没有明确指定数字的有效范围,但Qt中的支持仅限于双精度的有效范围和精度。字符串可以是任何有效的unicode字符串。数组是值的列表,对象是键/值对的集合。对象中的所有键都是字符串,并且对象不能包含任何重复的键。
JSON的文本表示包含方括号([…])中的数组和花括号({…})中的对象。数组和对象中的条目用逗号分隔。对象中键和值之间的分隔符是冒号(:)。
一个简单的JSON文档,对一个人、他的/她的年龄、地址和电话号码进行编码,其内容如下:
{
"FirstName": "Zhang",
"LastName": "San",
"Age": 24,
"Address":
{
"Street": "Downing Street 10",
"City": "ShangHai",
"Country": "Great Britain"
},
"Phone numbers":
[
"+22 1234567",
"+22 2345678"
]
}
上面的示例由一个具有5个键/值对的对象组成。其中两个值是字符串,一个是数字,另一个是对象,最后一个是数组。
有效的JSON文档是数组或对象,因此文档总是以方括号或花括号开头。
所有JSON类都是基于值的隐式共享类。
Qt中的JSON支持包括以下类:
QJsonArray封装JSON数组
QJsonDocument读取和写入JSON文档方法
QJsonObject封装JSON对象
QJsonParseError用于报告JSON解析过程中的错误
QJsonValue将值封装为JSON
QJsonObject::const_iteratorQJsonObject::const_isterator类为QJsonObjects提供了一个STL风格的常量迭代器
QJsonObject::iteratorQJsonObject::iterator类为QJsonObject提供了一个STL风格的非常量迭代器
QJsonValue类将值封装在JSON中。
JSON中的值可以是6种基本类型之一:
JSON是一种存储结构化数据的格式。它有6种基本数据类型:
QJsonValue::Type 描述
QJsonValue::Null null值
QJsonValue::Bool 存储的是bool值,可以通过toBool转换为bool类型
QJsonValue::Double 存储的是double值,可以通过toDouble转换为double类型
QJsonValue::String 存储的是字符串类型,可以通过toString转换为QString类型
QJsonValue::Array 存储的是数组,可以通过toArray转换为QJsonArray类型
QJsonValue::Object 存储的json对象,可以通过toObject转换为QJsonObject类型
值可以表示上述任何数据类型。此外,QJsonValue有一个特殊的标志来表示未定义的值。这可以使用isUndefined()查询。
可以使用type()或isBool()、isString()等访问器查询值的类型。同样,可以使用toBool(()、toString()等等将值转换为存储在其中的类型。
值是内部严格类型化的,与QVariant相反。它不会尝试进行任何隐式类型转换。这意味着转换为未存储在值中的类型将返回默认构造的返回值。
可以通过type方法获取当前存储的类型,例如:
QJsonValue value(false);
qDebug() << value.type();
当然还有一些类型判断,如下:
QJsonValue value(false);
qDebug() << value.isBool();
qDebug() << value.isObject();
…
可以通过支持的类型直接构建,例如:
QJsonValue value(false);
QJsonValue value(1);
QJsonValue value("A");
QJsonValue value(QJsonArray({ 1, 2 }));
QJsonValue value(QJsonObject({ { "A", "zhangsan" }, { "B", 10 } }));
1、QJsonObject类封装了一个JSON对象。
2、JSON对象是键值对的列表,其中键是唯一的字符串,值由QJsonValue表示。
3、QJsonObject可以转换为QVariantMap,也可以从QVariantMap转换。您可以使用size()、insert()和remove()条目查询(键、值)对的数量,并使用标准C++迭代器模式对其内容进行迭代。
4、QJsonObject是一个隐式共享的类,只要没有修改,它就与创建它的文档共享数据。
5、您可以通过QJsonDocument将对象转换为基于文本的JSON。
1 . 可以通过初始化列表构造QJsonObject对象,例如:
QJsonObject object({ { "year", "2022" }, { "month", 12 }, {"day", 6} });
qDebug().noquote() << "3333333333333333333333" << QJsonDocument(object).toJson();
输出:
3333333333333333333333 {
"day": 6,
"month": 12,
"year": "2022"
}
2 . QVarientMap和QVarientHash里放的就是多个键值对,也正好符合Json对象的形式,所以,QJsonObject提供了下面两个静态方法:
static QJsonObject fromVariantMap(const QVariantMap &map);
static QJsonObject fromVariantHash(const QVariantHash &map);
当然也可以将QJsonObject转换为QVarientMap或者QVarientHash
QVariantHash toVariantHash() const;
QVariantMap toVariantMap() const;
3 . 动态构建QJsonObject,通过使用insert方法添加键值对,例如:
object.insert("A", "zhangsan");
object.insert("B", 15);
qDebug().noquote() << QJsonDocument(object).toJson();
输出:
{
“B”: 15,
“A”: “zhangsan”
}
QJsonObject中插入键值对后是会按键排序的,不会保持insert的顺序,类似QMap。
QJsonObject中存储容量是有上限的,源码中,插入新值会执行reserveSpace,里面有个容量上限
int Base::reserveSpace(uint dataSize, int posInTable, uint numItems, bool replace)
{
Q_ASSERT(posInTable >= 0 && posInTable <= (int)length);
if (size + dataSize >= Value::MaxSize) {
qWarning("QJson: Document too large to store in data structure %d %d %d", (uint)size, dataSize, Value::MaxSize);
return 0;
}
...
}
enum {
MaxSize = (1<<27) - 1
};
QJsonObject object({ { "A", "zhangsan" }, { "B", 15 } });
// 取值
qDebug() << object.value("A");
qDebug() << object["A"];
// 查找
qDebug() << object.contains("A");
auto iter = object.find("A");
// 遍历
for (auto iter = object.begin(); iter != object.end(); iter++)
qDebug() << iter.key() << iter.value();
// 删除
object.remove("A");
1、QJsonArray类封装了一个JSON数组。
2、JSON数组是一个值列表。可以通过从数组中插入和删除QJsonValue来操作列表。
3、QJsonArray可以与QVariantList进行转换。您可以使用size()、insert()和removeAt()查询条目的数量,并使用标准C++迭代器模式对其内容进行迭代。
4、QJsonArray是一个隐式共享类,只要没有修改,它就与创建它的文档共享数据。
5、您可以通过QJsonDocument将数组转换为基于文本的JSON。
1、初始化列表
QJsonArray array({1});
QJsonArray array2({"zhouyi" ,"zhouer"});
2、动态初始化
QJsonArray array;
array.append(2);
array.append(QJsonObject({ { "name", "XiaoMing" }, { "age", 25 } }));
array.insert(0, "XiaoTian");
qDebug().noquote() << "111111111111111111111111" << QJsonDocument(array).toJson();
输出:
111111111111111111111111 [
"XiaoTian",
2,
{
"age": 25,
"name": "XiaoMing"
}
]
3.从QStringList和QVarient转换成QJsonArray
static QJsonArray fromStringList(const QStringList &list);
static QJsonArray fromVariantList(const QVariantList &list);
QJsonArray array;
QStringList str;
str << "1" << "2" << "3" << "4" << "5";
array = QJsonArray::fromStringList(str);
qDebug().noquote() << "111111111111111111111111" << QJsonDocument(array).toJson();
QJsonArray array1;
QVariantList list;
QVariantMap map;
for(int i = 0; i < 3; i++)
{
map.clear();
map["zhangsan"] = QString("A_%1").arg(i);
map["lisi"] = QString("B_%1").arg(i);
map["wangwu"] = QString("C_%1").arg(i);
list.append(map);
}
array1 = QJsonArray::fromVariantList(list);
qDebug().noquote() << "22222222222222222222" << QJsonDocument(array1).toJson();
输出:
111111111111111111111111 [
"1",
"2",
"3",
"4",
"5"
]
2222222222222222222222 [
{
"lisi": "B_0",
"wangwu": "C_0",
"zhangsan": "A_0"
},
{
"lisi": "B_1",
"wangwu": "C_1",
"zhangsan": "A_1"
},
{
"lisi": "B_2",
"wangwu": "C_2",
"zhangsan": "A_2"
}
]
// 增
QJsonArray array({"zhouyi", "zhouer"});
qDebug() << "1111111111111111" <
1、QJsonDocument类提供了一种读写JSON文档的方法。
2、QJsonDocument是一个包装完整JSON文档的类,可以从UTF-8编码的基于文本的表示以及Qt自己的二进制格式读取和写入该文档。
3、可以使用QJsonDocument::fromJson()将JSON文档从基于文本的表示转换为QJsonDocument。toJson()将其转换回文本。解析器非常快速高效,并将JSON转换为Qt使用的二进制表示。
4、可以使用查询解析文档的有效性!isNull()
5、可以使用isArray()和isObject()查询文档是否包含数组或对象。可以使用array()或object()检索文档中包含的数组或对象,然后读取或操作。
6、也可以使用fromBinaryData()或fromRawData()从存储的二进制表示创建文档。
QJsonDocument支持从QJsonObject和QJsonArray构造:
QJsonDocument(const QJsonObject &object)
QJsonDocument(const QJsonArray &array)
或者通过set方法设置数据:
void setArray(const QJsonArray &array)
void setObject(const QJsonObject &object)
然后,使用toJson方法序列化成QByteArray,例如:
QJsonObject object({ { "year", "2022" }, { "month", 12 }, {"day", 6} });
qDebug().noquote() << "3333333333333333333333" << QJsonDocument(object).toJson();
输出:
3333333333333333333333 {
"day": 6,
"month": 12,
"year": "2022"
}
另外,toJson可以传QJsonDocument::Compact参数来获取压缩后的序列化结果,压缩的结果如下:
qDebug().noquote() << "33" << QJsonDocument(object).toJson(QJsonDocument::Compact);
33 {"day":6,"month":12,"year":"2022"}
QJsonDocument提供了静态方法fromJson来创建QJsonDocument对象:
// error参数用于获取转换错误时的详细错误信息
static QJsonDocument fromJson(const QByteArray &json, QJsonParseError *error = nullptr)
然后可以判断是否是object或者array:
bool isArray() const
bool isObject() const
最后可以通过object和array方法取得QJsonObject或者QJsonArray对象:
QJsonObject object() const
QJsonArray array() const
了解完上面这些内容,日常使用QJson应该没有问题了。
博客相关的内容参考了QtCreater的帮助文档以及网上好的文档的编写,其实还有还多相关的知识没有提到,后续会有相应的补充,大家一起学习一起进步,有好的内容可以分享给我