上一章我们了解了如何使用 QJson 处理 JSON 文档。QJson 是一个基于 Qt 的第三方库,适用于 Qt4 和 Qt5 两个版本。不过,如果你的应用仅仅需要考虑兼容 Qt5,其实已经有了内置的处理函数。Qt5 新增加了处理 JSON 的类,与 XML 类库类似,均以 QJson 开头,在 QtCore 模块中,不需要额外引入其它模块。Qt5 新增加六个相关类:
QJsonArray | 封装 JSON 数组 |
QJsonDocument | 读写 JSON 文档 |
QJsonObject | 封装 JSON 对象 |
QJsonObject::iterator | 用于遍历QJsonObject 的 STL 风格的非 const 遍历器 |
QJsonParseError | 报告 JSON 处理过程中出现的错误 |
QJsonValue | 封装 JSON 值 |
我们还是使用前一章的 JSON 文档,这次换用QJsonDocument
来解析。注意,QJsonDocument
要求使用 Qt5,本章中所有代码都必须在 Qt5 环境下进行编译运行。
QString json("{" "\"encoding\" : \"UTF-8\"," "\"plug-ins\" : [" "\"python\"," "\"c++\"," "\"ruby\"" "]," "\"indent\" : { \"length\" : 3, \"use_space\" : true }" "}"); QJsonParseError error; QJsonDocument jsonDocument = QJsonDocument::fromJson(json.toUtf8(), &error); if (error.error == QJsonParseError::NoError) { if (jsonDocument.isObject()) { QVariantMap result = jsonDocument.toVariant().toMap(); qDebug() << "encoding:" << result["encoding"].toString(); qDebug() << "plugins:"; foreach (QVariant plugin, result["plug-ins"].toList()) { qDebug() << "\t-" << plugin.toString(); } QVariantMap nestedMap = result["indent"].toMap(); qDebug() << "length:" << nestedMap["length"].toInt(); qDebug() << "use_space:" << nestedMap["use_space"].toBool(); } } else { qFatal(error.errorString().toUtf8().constData()); exit(1); }
这段代码与前面的几乎相同。QJsonDocument::fromJson()
可以由QByteArray
对象构造一个QJsonDocument
对象,用于我们的读写操作。这里我们传入一个QJsonParseError
对象的指针作为第二个参数,用于获取解析的结果。如果QJsonParseError::error()
的返回值为QJsonParseError::NoError
,说明一切正常,则继续以QVariant
的格式进行解析(由于我们知道这是一个 JSON 对象,因此只判断了isObject()
。当处理未知的 JSON 时,或许应当将所有的情况都考虑一边,包括isObject()
、isArray()
以及isEmpty()
)。
也就是说,如果需要使用QJsonDocument
处理 JSON 文档,我们只需要使用下面的代码模板:
// 1. 创建 QJsonParseError 对象,用来获取解析结果 QJsonParseError error; // 2. 使用静态函数获取 QJsonDocument 对象 QJsonDocument jsonDocument = QJsonDocument::fromJson(json.toUtf8(), &error); // 3. 根据解析结果进行处理 if (error.error == QJsonParseError::NoError) { if (!(jsonDocument.isNull() || jsonDocument.isEmpty())) { if (jsonDocument.isObject()) { // ... } else if (jsonDocument.isArray()) { // ... } } } else { // 检查错误类型 }
将QVariant
对象生成 JSON 文档也很简单:
QVariantList people; QVariantMap bob; bob.insert("Name", "Bob"); bob.insert("Phonenumber", 123); QVariantMap alice; alice.insert("Name", "Alice"); alice.insert("Phonenumber", 321); people << bob << alice; QJsonDocument jsonDocument = QJsonDocument::fromVariant(people); if (!jsonDocument.isNull()) { qDebug() << jsonDocument.toJson(); }
这里我们仍然使用的是QJsonDocument
,只不过这次我们需要使用QJsonDocument::fromVariant()
函数获取QJsonDocument
对象。QJsonDocument
也可以以二进制格式读取对象,比如QJsonDocument::fromBinaryData()
和QJsonDocument::fromRawData()
函数。当我们成功获取到QJsonDocument
对象之后,可以使用toJson()
生成 JSON 文档。
以上介绍了当我们有一个 JSON 文档时,如何使用QJsonDocument
进行处理。如果我们没有 JSON 文档,那么我们可以使用QJsonDocument
的setArray()
和setObject()
函数动态设置该对象,然后再生成对应的 JSON 格式文档。不过这部分需求比较罕见,因为我们直接可以从QVariant
值类型获取。
Qt5 提供的 JSON 类库直接支持隐式数据共享,因此我们不需要为复制的效率担心。
10 评论
Can you please send your phone number to my email: kqzca@yahoo.ca? I have Qt projects that I don't have enough time to finish. If you are interested then we can talk about the details.
能看懂中文却不愿说中文的渣渣
也有可能人家没有中文输入法,对别人宽容一点,好不
别人不会中文的,你的网页被google自动翻译后,才被他看到,所以以为你写的是英文文档。
只有json的读取和写入操作,没有写出 修改json的方法呀?
QJsonDocument jsonDocument = QJsonDocument::fromJson(json.toUtf8(), &error);
QJsonObject jb(jsonDocument.object());
jb.insert("encoding",QJsonValue::fromVariant("fff"));
jsonDocument.setObject(jb);
我想到只有这种方法,但是看起来好像性能会很差呀,这种操作方法会不会出现复制整块内存?
大致是这种方式。文档中有 JSON Save Game Example 可以参考下。至于会不会复制内存,不清楚你说的是哪块内存?
如果里面包含数组,应该怎样循环读取出来,希望有这方面的代码,谢谢。
QVariantList people;
QVariantMap bob;
这里people的类型是QList,不能 people<<bob 吧
您好,请问有什么方法可以在QT4里使用qjsondocument
QJsonDocument 是 Qt 5 的新类,Qt 4 中需要使用第三方库来解析 JSON,比如 QJson 或者 qt-json