QT json基本用法

目录

  • json格式简介
  • QJson模块介绍
    • QJsonValue、QJsonObject、QJsonArray
  • QJson模块基本用法
    • QJsonValue
      • 支持的类型
      • 构建
    • QJsonObject
      • 构建
      • 注意
      • 取值、 查找、遍历、删除
    • QJsonArray
      • 构建
      • 取值、删除、修改、遍历
    • QJsonDocument之序列化和反序列化
      • 序列化
      • 反序列化
  • 总结

json格式简介

json可以理解为一种多级键值对的结构,例如:

{
	"name" : "Xiao Ming",
	"age" : 10
}

上面这个简单结构表示一个学生信息,包含2个键值对。
我们来看一个复杂点的:

{
	"students" : [
		{
			"name" : "Xiao Ming",
			"age" : 10
		},
		{
			"name" : "Xiao Hong",
			"age" :8
		}
	],
	"classes" : ["one", "two", "three"],
	"teacher" : {
		"name" : "FangFang",
		"age" : 23
	}
}

上面这个多级结构表示多个学生和多个班级

  • 键students对应的值是一个数组,数组里面放了2个json对象;
  • 键classes对应的值是一个数组,数组里面放了3个字符串;
  • 键teacher对应的值是一个json对象,里面放的是老师信息。

可以做一个简单的总结:

  • 大括号{}表示一个json对象
  • 中括号[]表示一个json数组,数组内容可以是普通的值类型,也可以是一个json对象
  • 冒号左边是键,右边是值,值可以基础类型、数组和json对象。

QJson模块介绍

Qt的Json模块主要涉及3个数据结构类(QJsonObject、QJsonValue、QJsonArray)和1个序列化和反序列化类(QJsonDocument)。下面我们介绍下这4个基础类。

QJsonValue、QJsonObject、QJsonArray

  • QJsonValue表示一个Json值,对应例子中冒号:右边的部分
  • QJsonObject表示一个Json对象,就是例子中大括号{}的部分。
  • QJsonArray表示一个Json值数组,对应例子中中括号[]的部分
  • QJsonDocument是负责序列化和反序列化,比如将Json对象转换为QByteArray,将QByteArray转化为Json对象等。

QJson模块基本用法

QJsonValue

支持的类型

QJsonValue表示Json值,前面说过,值可以是基本类型、QJsonArray和QJsonObject,具体如下:

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类型

可以通过type方法获取当前存储的类型,例如:

QJsonValue value(false);
qDebug() << value.type();

当然还有一些类型判断,如下:

QJsonValue value(false);
qDebug() << value.isBool();
qDebug() << value.isObject();
...

构建

可以通过支持的类型直接构建,例如:

QJsonValue value(false);
QJsonValue value(1);
QJsonValue value("XiaoMing");
QJsonValue value(QJsonArray({ 1, 2 }));
QJsonValue value(QJsonObject({ { "name", "XiaoMing" }, { "age", 10 } }));

QJsonObject

构建

1 . 可以通过初始化列表构造QJsonObject对象,例如:

QJsonObject object({ { "name", "XiaoMing" }, { "age", 15 } });
qDebug().noquote() << QJsonDocument(object).toJson();

输出:

{
    "age": 15,
    "name": "XiaoMing"
}

2 . 另外大家发现没,上面初始化列表正好是个QVarientMap或者QVarientHash,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("name", "XiaoMing");
object.insert("age", 15);
qDebug().noquote() << QJsonDocument(object).toJson();

输出:

{
    "age": 15,
    "name": "XiaoMing"
}

注意

  1. QJsonObject中插入键值对后是会按键排序的,不会保持insert的顺序,类似QMap。
  2. 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提供了容器类的基本都有的常规方法,如下:

QJsonObject object({ { "name", "XiaoMing" }, { "age", 15 } });

// 取值
qDebug() << object.value("name");
qDebug() << object["name"];

// 查找
qDebug() << object.contains("name");
auto iter = object.find("name");

// 遍历
for (auto iter = object.begin(); iter != object.end(); iter++)
    qDebug() << iter.key() << iter.value();

// 删除
object.remove("name");

QJsonArray

QJsonArray可以理解为Array of QJsonValue,里面放置的是一组QJsonValue,而不是QJsonObject。

构建

1.初始化列表构建

QJsonArray array({1});
QJsonArray array({"XiaoMing", "XiaoHong"});

2.动态构建

QJsonArray array;
array.append(1);
array.append(QJsonObject({ { "name", "XiaoMing" }, { "age", 10 } }));
array.insert(0, "XiaoMing");
qDebug().noquote() << QJsonDocument(array).toJson();

输出:

[
    "XiaoMing",
    1,
    {
        "age": 10,
        "name": "XiaoMing"
    }
]

3.从QStringList和QVarient转换

static QJsonArray fromStringList(const QStringList &list);
static QJsonArray fromVariantList(const QVariantList &list);

取值、删除、修改、遍历

// 取值
QJsonArray array({"XiaoMing", "XiaoHong"});
qDebug() << array[0];

// 删除
array.remove(0);

// 替换
array.replace(0, "DaWang");

// 遍历
for (auto value : array)
    qDebug() << value;

QJsonDocument之序列化和反序列化

QJsonDocument可以理解为一个QJson序列化和反序列化的工具类。

序列化

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({ { "name", "XiaoMing" }, { "age", 15 } });
qDebug().noquote() << QJsonDocument(object).toJson();

输出:

{
    "age": 15,
    "name": "XiaoMing"
}

另外,toJson可以传QJsonDocument::Compact参数来获取压缩后的序列化结果,压缩的结果如下:

{"age":12,"name":"XiaoMing"}

反序列化

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

举例:

auto jsonDocument = QJsonDocument::fromJson("{\"name\":\"XiaoMing\",\"age\":12}");
auto jsonObj = jsonDocument.object();
qDebug().noquote() << QJsonDocument(jsonObj).toJson();

输出:

{
    "age": 12,
    "name": "XiaoMing"
}

总结

了解完上面这些内容,日常使用QJson应该没有问题了。
由于篇幅原因,其实还有很多东西没有提到,大家可以在QtCreater的帮助界面浏览各个类的详细信息,或者直接阅读源代码。
题外话:今天本来想看看源码找出QJsonObject为啥会按键排序,结果没找到,连用什么数据结构存储键值对数据都没找到,惭愧(只看到下面可能有个大数组),如果有大佬知道,求指点,多谢。

你可能感兴趣的:(qt,json,qt)