目录
前言
一,QJsonDocument
二,QJsonArray
三,QJsonObject
四,QJsonValue
五,案例答疑解惑
1,测试读写的 test.json 文件内容(文件路径 E:\test.json)
2,所需要的头文件
3,写 Json 文件接口实现
4,读 Json 文件接口实现
前言
从 Qt 5.0 就开始提供处理 Json 数据的操作支持,JSON是一种对源自Javascript的对象数据进行编码的格式,但现在广泛用作互联网上的数据交换格式,Qt中的JSON支持提供了一个易于使用的C++ API来解析,修改和保存JSON数据。
Qt中所有的 JSON 类都是基于值的隐式共享类(隐式共享类的意思是只要它没有被修改,它就与创建它的文档共享数据)。常用的相关类为如下表格的前四个:
Json 类 | 介绍 |
QJsonDocument | 它封装了一个完整的 JSON 文档,可以从基于UTF-8编码的文本表示和Qt自己的二进制格式来对该文档进行读写操作。 |
QJsonArray | JSON 数组是一个值的列表。可以通过从数组中插入和删除 QJsonValue 来操作该列表。 |
QJsonObject | JSON 对象是键值对的列表,其中键是唯一的字符串,值由 QJsonValue 表示。 |
QJsonValue | 该类封装了 JSON 支持的数据类型。 |
QJsonParseError | 用于报告 JSON 解析过程中的错误。 |
一,QJsonDocument
QJsonDocument 是一个封装完整JSON文档的类,可以从基于UTF-8编码的文本表示和Qt自己的二进制格式来对该文档进行读写操作。使用 QJsonDocument::fromJson() 可以将JSON文档从基于文本的表示形式转换为 QJsonDocument,使用 QJsonDocument::toJson() 可以将其转换回文本形式。解析器非常快速和有效,并可以使用 QJsonDocument::toBinaryData() 将 JSON 转换为Qt使用的二进制表示。
因为 QJsonObject 和 QJsonArray 这两个对象中的数据是不能直接转换为字符串类型的,如果要进行数据传输或者数据的持久化保存,需要对数据进行序列化和反序列化操作,详细如下
- QJsonObject 或者 QJsonArray 序列化为 字符串
1. 创建 QJsonDocument 对象
QJsonDocument::QJsonDocument(const QJsonObject &object); //个人常用 QJsonDocument::QJsonDocument(const QJsonArray &array); QJsonDocument::QJsonDocument(const QJsonDocument &other); //几乎不用 QJsonDocument::QJsonDocument(); //或者创建一个空对象,使用以下两个方法设置数据 QJsonDocument::setArray(const QJsonArray &array); QJsonDocument::setObject(const QJsonObject &object);
2. 将文件对象中的数据进行序列化
QByteArray QJsonDocument::toBinaryData() const; //二进制格式的json字符串 QByteArray QJsonDocument::toJson(JsonFormat format = Indented) const; //文本格式 个人常用
3.使用得到的字符串进行数据传输,或者磁盘文件持久化
- 字符串 反序列化为 QJsonObject 或者 QJsonArray
1. 将通过网络通信或磁盘文件读取得到的 Json 格式字符串转换为 QJsonDocument 对象
QJsonDocument QJsonDocument::fromJson(const QByteArray &json, QJsonParseError *error = Q_NULLPTR); //个人常用 QJsonDocument QJsonDocument::fromBinaryData(const QByteArray &data, DataValidation validation = Validate); QJsonDocument QJsonDocument::fromRawData(const char *data, int size, DataValidation validation = Validate) QJsonDocument QJsonDocument::fromVariant(const QVariant &variant)
2. 将文档对象转换为 Json 数组 或 Json 对象
bool QJsonDocument::isArray() const; //判断文档对象中存储的数据是不是数组 bool QJsonDocument::isObject() const //判断文档对象中存储的数据是不是json对象 QJsonObject QJsonDocument::object() const; //文档对象中的数据转换为json对象 QJsonArray QJsonDocument::array() const; //文档对象中的数据转换为json数组
3.通过调用 QJsonArray , QJsonObject 类提供的 API 读取存储在 QJsonDocument 对象中的数据
二,QJsonArray
QJsonArray 封装了 Json 中的数组,数组里面的所有元素统一为 QJsonValue 类型。常用API函数如下,详细参照官方文档:
- 创建一个 Json 数组
QJsonArray::QJsonArray(); //创建一个空数组 QJsonArray::QJsonArray(const QJsonArray &other) //拷贝构造,不常用 QJsonArray::QJsonArray(std::initializer_list
args) //没用过 - 添加数据
void QJsonArray::append(const QJsonValue &value); //在数组尾部追加 void QJsonArray::insert(int i, const QJsonValue &value); //将value插入到i的位置 iterator QJsonArray::insert(iterator before, const QJsonValue &value); //std 知识 void QJsonArray::prepend(const QJsonValue &value); //将value添加到数组头部 void QJsonArray::push_back(const QJsonValue &value); //将value添加到数组尾部 void QJsonArray::push_front(const QJsonValue &value); //将value添加到数组头部
- 删除数据
iterator QJsonArray::erase(iterator it); //基于迭代器删除 void QJsonArray::pop_back(); //删除尾部 void QJsonArray::pop_front(); //删除头部 void QJsonArray::removeAt(int i); //删除i位置的元素 void QJsonArray::removeFirst(); //删除头部 void QJsonArray::removeLast(); //删除尾部 QJsonValue QJsonArray::takeAt(int i); //删除i位置的原素, 并返回删除的元素的值
- 获取数组中元素个数
int QJsonArray::count() const; int QJsonArray::size() const;
- 获取数组中的元素值
QJsonValue QJsonArray::at(int i) const; //获取指定i位置的元素 QJsonValue QJsonArray::first() const; //头部元素 QJsonValue QJsonArray::last() const; //尾部元素 QJsonValueRef QJsonArray::operator[](int i); //注意这获取的是指定i位置的元素引用 QVariantList QJsonArray::toVariantList() const;
三,QJsonObject
QJsonObject 是键值对的列表,里面可以存储多个键值对,其中键是惟一的字符串,值由QJsonValue 表示。常用API函数如下,详细参照官方文档:
- 创建一个 Json 对象
QJsonObject::QJsonObject(); // 构造空对象 QJsonObject::QJsonObject(std::initializer_list
> args); QJsonObject::QJsonObject(const QJsonObject &other); - 将键值对添加到对象中
iterator QJsonObject::insert(const QString &key, const QJsonValue &value);
- 删除键值对
void QJsonObject::remove(const QString &key); QJsonValue QJsonObject::take(const QString &key); // 删除并返回key对应的value值
- 获取对象中键值对个数
int QJsonObject::count() const; int QJsonObject::size() const; int QJsonObject::length() const;
- 通过 key 得到 value
QJsonValue QJsonObject::value(const QString &key) const; // utf8格式 QJsonValue QJsonObject::value(QLatin1String key) const; // 字符串不支持中文 QJsonValue QJsonObject::operator[](const QString &key) const; QJsonValue QJsonObject::operator[](QLatin1String key) const;
- 通过 key 查找对象中是否有该键值对
iterator QJsonObject::find(const QString &key); //重载类型的接口会根据输入的参数自行选择 const_iterator QJsonObject::find(const QString &key) const; bool QJsonObject::contains(const QString &key) const; bool QJsonObject::contains(QLatin1String key) const;
四,QJsonValue
QJsonValue 类用JSON封装了一个值,该值在内部是严格类型的,与QVariant相反,它不会尝试进行任何隐式类型转换。这意味着转换为不存储在值中的类型将返回一个默认的构造返回值。值的类型可以是如下六种基本数据类型:
布尔类型 QJsonValue::Bool 浮点类型(包括整形) QJsonValue::Double 字符串类型 QJsonValue::String Json 数组类型 QJsonValue::Array Json 对象类型 QJsonValue::Object 空值类型 QJsonValue::Null - 创建一个 QJsonValue 对象
QJsonValue::QJsonValue(const QJsonArray &a); //Json数组 QJsonValue::QJsonValue(const QJsonObject &o); //Json对象 QJsonValue::QJsonValue(const QJsonValue &other); //拷贝构造 QJsonValue::QJsonValue(Type type = Null); //空值类型 QJsonValue::QJsonValue(bool b); //布尔类型 //整型和浮点型 QJsonValue::QJsonValue(double n); QJsonValue::QJsonValue(int n); QJsonValue::QJsonValue(qint64 n); //字符串 QJsonValue::QJsonValue(const QString &s); QJsonValue::QJsonValue(QLatin1String s); QJsonValue::QJsonValue(const char *s); //将variant转换为QJsonValue并返回 [static] QJsonValue QJsonValue::fromVariant(const QVariant &variant);
- 判断 QJsonValue 对象的内部封装的数据类型
bool QJsonValue::isArray() const; //是否是Json数组 bool QJsonValue::isObject() const; //是否是Json对象 bool QJsonValue::isBool() const; //是否是布尔类型 bool QJsonValue::isDouble() const; //是否是浮点类型(整形也是通过该函数判断) bool QJsonValue::isNull() const; //是否是空值类型 bool QJsonValue::isString() const; //是否是字符串类型 bool QJsonValue::isUndefined() const; //是否是未定义类型(无法识别的类型)
- 将 QJsonValue 对象转换成内部封装的基础数据类型
QJsonArray QJsonValue::toArray(const QJsonArray &defaultValue) const; //转换为Json数组 QJsonArray QJsonValue::toArray() const; bool QJsonValue::toBool(bool defaultValue = false) const; //转换为布尔类型 double QJsonValue::toDouble(double defaultValue = 0) const; //转换为浮点类型 int QJsonValue::toInt(int defaultValue = 0) const; //转换为整形 QJsonObject QJsonValue::toObject() const; //转换为Json对象 QJsonObject QJsonValue::toObject(const QJsonObject &defaultValue) const; QString QJsonValue::toString() const; //转换为字符串类型 QString QJsonValue::toString(const QString &defaultValue) const;
- QJsonValue fromVariant(const QVariant &variant); 该静态接口的参数转换规则如下表:
接口输入参数 接口返回值类型 QMetaType::Nullptr QJsonValue::Null
QMetaType::Bool QJsonValue::Bool
QMetaType::Int QMetaType::UInt
QMetaType::LongLong
QMetaType::ULongLong
QMetaType::Float
QMetaType::Double
QJsonValue::Double
QMetaType::QString QJsonValue::String
QMetaType::QStringList QMetaType::QVariantList
QJsonValue::Array
QMetaType::QVariantMap QMetaType::QVariantHash
QJsonValue::Object
五,案例答疑解惑
1,测试读写的 test.json 文件内容(文件路径 E:\test.json)
{ "FirstName": "Fu", "LastName": "Cong", "Age": 24, "Address": { "Street": "首创悦榕汇", "City": "BeiJing", "Country": "BeiJing" }, "Phone numbers": [ "+44 12345", "+44 678910" ] }
2,所需要的头文件
#include
#include #include #include #include #include 3,写 Json 文件接口实现
void writeJson() { QJsonObject obj_root; obj_root.insert("FirstName","Fu"); obj_root.insert("LastName","Cong"); obj_root.insert("Age",24); QJsonObject subObj_addr; subObj_addr.insert("Street","首创悦榕汇"); subObj_addr.insert("City","BeiJing"); subObj_addr.insert("Country","BeiJing"); obj_root.insert("Address",subObj_addr); QJsonArray arr_phone; arr_phone.append("+44 12345"); arr_phone.append("+44 678910"); obj_root.insert("Phone numbers",arr_phone); QJsonDocument jsonDocu(obj_root); QByteArray jsonData = jsonDocu.toJson(); QFile file("E:\\test.json"); if(file.open(QIODevice::WriteOnly)){ file.write(jsonData); file.close(); } }
效果图如下
4,读 Json 文件接口实现
void readJson() { QFile file("E:\\test.json"); QByteArray jsonData; if(file.open(QIODevice::ReadOnly)){ jsonData = file.readAll(); file.close(); } QJsonDocument jsonDocu = QJsonDocument::fromJson(jsonData); if(jsonDocu.isObject()){ QJsonObject obj_root = jsonDocu.object(); QStringList keys = obj_root.keys(); for(auto key : keys){ QJsonValue value = obj_root.value(key); if(value.isString()){ qDebug() << key <<": "<< value.toString(); }else if(value.isDouble()){ qDebug() << key <<": "<< value.toInt(); }else if(value.isArray()){ QJsonArray arr = value.toArray(); for(int i = 0; i < arr.count(); ++i){ if(arr.at(i).isString()){ qDebug() << key <<": "<< arr.at(i).toString(); } //这里就不判断是否为其它类型了,因为测试文件已知为字符串,要写也和上面类似,无限套娃 } }else if(value.isObject()){ QJsonObject subObj = value.toObject(); QStringList subKeys = subObj.keys(); for(auto subKey : subKeys){ QJsonValue subValue = subObj.value(subKey); if(subValue.isString()){ qDebug() << subKey <<": "<< subValue.toString(); } //这里就不判断是否为其它类型了,因为测试文件已知为字符串,要写也和上面类似,无限套娃 } } } } }
效果图如下
- QJsonValue fromVariant(const QVariant &variant); 该静态接口的参数转换规则如下表:
- 将 QJsonValue 对象转换成内部封装的基础数据类型
- 判断 QJsonValue 对象的内部封装的数据类型
- 创建一个 QJsonValue 对象
- 通过 key 查找对象中是否有该键值对
- 通过 key 得到 value
- 获取对象中键值对个数
- 删除键值对
- 将键值对添加到对象中
- 创建一个 Json 对象
- 获取数组中的元素值
- 获取数组中元素个数
- 删除数据
- 添加数据
- 创建一个 Json 数组
- 字符串 反序列化为 QJsonObject 或者 QJsonArray