Qt中的JSON支持

JSON介绍

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概述

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

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 } }));

QJsonObject

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");

JSON数组

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" <<array[0];

// 删
array.removeAt(0);

// 改
array.replace(0, "zhousan");

// 遍历
foreach (auto value , array)
    qDebug() << "2222222222222222" << value;

QJsonDocument

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的帮助文档以及网上好的文档的编写,其实还有还多相关的知识没有提到,后续会有相应的补充,大家一起学习一起进步,有好的内容可以分享给我

Qt,可以使用Qt提供的Json类来组织和解析数据。Qt从版本5.0开始提供了对Json支持。主要有四个与Json相关的类常用:QJsonDocument、QJsonArray、QJsonObject和QJsonValue。 QJsonDocument类封装了一个完整的JSON文档,可以从基于文本的UTF-8编码的表示以及Qt的二进制格式读取和写入该文档。 QJsonArray表示JSON数组,是一个值的列表。可以通过插入和删除QJsonValue来操作该列表。 QJsonObject表示JSON对象,是键值对的列表,其键是唯一的字符串,值由QJsonValue表示。 QJsonValue类封装了JSON支持的数据类型。 QJsonParseError类用于报告JSON解析过程的错误。 对于Json的使用,可以参考以上提到的类的文档和相关函数进行操作,根据具体的需求进行数据的组织和解析。Json格式的数据在Qt可以方便地进行处理,并且由于Json的数据格式与语言无关,因此在QtJson使用具有广泛的应用场景。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *3* [【QTQt Json 的操作](https://blog.csdn.net/qq_43331089/article/details/124582761)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *2* [【Qt专栏】QtJson的使用教程](https://blog.csdn.net/weixin_43729127/article/details/127522889)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值