JSON(JavaScript Object Notation,js对象标记)是一种轻量级的数据交换格式。它基于ECMAScript的一个子集,使用完全独立于编程语言的文本格式来存储和表示数据。简洁和清晰的的层次结构使得JSON成为理想的数据交换语言。易于人阅读和编写,同时也易于机器解析和生成,并有效的提升网络传输效率。关于JSON的更多解释,请参看 JSON官网

在Qt库中,为JSON的相关操作提供了完整的类支持,包括QJsonValue,QJsonObject,QJsonArray,QJsonDocument和QJsonParseError。其中,QJsonValue类表示json格式中的一个值;QJsonObject表示一个json对象;QJsonArray顾名思义表示一个json数组;QJsonDocument主要用来读写json文档;而QJsonParseError是用来表示json解析过程中出现的错误的方便类。下面,我们就来看看这些类的详细信息。

QJsonValue

QJsonValue类封装了一个json格式中的值。该值可以是如下6中基本类型:

  • bool QJsonValue::Bool
  • double QJsonValue::Double
  • string QJsonValue::String
  • array QJsonValue::Array
  • object QJsonValue::Object
  • null QJsonValue::Null
一个QJsonValue可以表示上面任何一种数据类型。此外,QJsonValue还有一个特殊的标志用来表示未定义的值。可以使用isUndefined()函数来进行判断。而一个QJsonValue中存储的类型可以通过type()或isBool(),isString()之类的函数进行查询。同样,QJsonValue中存储的值可以通过toBool(),toString()等函数转换到具体的类型。 QJsonValue中存储的值在内部是强类型的,并且和QVariant相反,它不会尝试进行任何的隐式类型转换。这意味着将QJsonValue转换成一个不是它存储的类型,将返回一个该类型的模型构造函数返回的值。 其实,说到QJsonValue,还有另一个类要说,QJsonValueRef,该类是一个对于QJsonArray和QJsonObject来说的一个帮助类。当你获得一个QJsonValueRef类的对象后,你可以把它当做一个QJsonValue对象的应用来使用。如果你向他赋值,该值会实际作用到底层的QJsonArray或者QJsonObject对象中的元素上。而要想使用该类,可以使用一下的两个方法:
  • QJsonArray::operator[](int i)
  • QJsonObject::operator[](const QString& key)const;
下面来看一下QJsonValue的构造函数:
QJsonValue(Type type = Null)
QJsonValue(bool b)
QJsonValue(double n)
QJsonValue(int n)
QJsonValue(qint64 n)
QJsonValue(const QString &s)
QJsonValue(QLatin1String s)
QJsonValue(const char *s)
QJsonValue(const QJsonArray &a)
QJsonValue(const QJsonObject &o)
QJsonValue(const QJsonValue &other)
可以看到,该类主要是对基本类型的一个包装。 QJsonObject类封装了一个json对象。一个json对象是一个键值对的列表,其中key是唯一的字符串,而值就是一个我们上面讲到的QJsonValue。一个QJsonObject的对象可以转换到QVariantMap,要可以由QVariantMap转换得到。 我们可以使用size()函数来查询一个QJsonObject中存储的键值对的个数;使用insert()和remove()来插入或从中删除键值对;还可以使用标准的C++迭代器来遍历它。 QJsonObject类是一个隐式共享类。 其构造函数如下:
QJsonObject()
QJsonObject(std::initializer_list<QPair<QString, QJsonValue> > args)
QJsonObject(const QJsonObject &other)
我们可以使用初始化列表来快速的构建一个QJsonObject对象。如下:
  QJsonObject object
      {"property1", 1},
      {"property2", 2}
  };
如此之外,比较常用的就是insert()函数了:
iterator QJsonObject::insert(const QString &key, const QJsonValue &value)
一般,我们可以先定义一个空的QJsonObject对象,然后使用该函数向其中插入需要的键值对。如果新插入的key已存在,那么会进行替换。 下面,我们通过一个例子还使用该类构造如下json字符串:{"name":"lily", "age":23, "addr":{"city":"xxx", "province":"yyy"}} 代码如下:
#include <QCoreApplication>
#include <QDebug>
#include <QJsonObject>
int main(int argc, char *argv[])
    QCoreApplication a(argc, argv);
    QJsonObject obj;
    obj.insert("name", "lily");
    obj.insert("age", 23);
    QJsonObject addr;
    addr.insert("city", "guangzhou");
    addr.insert("province", "guangdong");
    obj.insert("addr", addr);
    qDebug() << obj;
    return a.exec();
}
我们先构建了一个QJsonObject对象obj,然后向其中插入姓名和年龄键值对;因为地址又是一个QJsonObject,所以我们又构建了addr对象,向其中插入城市和省份,最后,将该QJsonObject做为地址键值对的值,插入到obj中。打印结果如下:
QJsonArray()
QJsonArray(std::initializer_list<QJsonValue> args)
QJsonArray(const QJsonArray &other)
我们也可以像上面那样,使用一个初始化列表来构建一个QJsonArray对象:
QJsonArray array = { 1, 2.2, QString() };
在此我们只使用了单个的值,没有使用键值对。其实,这样的json对象,一般我们就称为数组。 和QJsonObject一样,我们一般也是通过它的insert()函数来生成我们需要的json数组:
void insert(int i, const QJsonValue &value)
iterator insert(iterator before, const QJsonValue &value)
下面,我们继续上面的例子,来生成一个表示人物信息的列表。代码如下:
#include <QCoreApplication>
#include <QDebug>
#include <QJsonObject>
#include <QJsonArray>
int main(int argc, char *argv[])
    QCoreApplication a(argc, argv);
    QJsonObject obj1;
    obj1.insert("name", "lily");
    obj1.insert("age", 23);
    QJsonObject addr1;
    addr1.insert("city", "guangzhou");
    addr1.insert("province", "guangdong");
    obj1.insert("addr", addr1);
    qDebug() << obj1;
    QJsonObject obj2;
    obj2.insert("name", "tom");
    obj2.insert("age", 24);
    QJsonObject addr2;
    addr2.insert("city", "shenzhen");
    addr2.insert("province", "guangdong");
    obj2.insert("addr", addr2);
    qDebug() << obj2;
    QJsonObject obj3;
    obj3.insert("name", "jerry");
    obj3.insert("age", 24);
    QJsonObject addr3;
    addr3.insert("city", "foshan");
    addr3.insert("province", "guangdong");
    obj3.insert("addr", addr3);
    qDebug() << obj3;
    QJsonArray array;
    array.push_back(obj1);
    array.push_back(obj2);
    array.push_back(obj3);
    qDebug() << array;
    return a.exec();
 
在此,我们只是简单的构建了三个人物的QJsonObject对象,然后将它们放入一个QJsonArray中。输入结果如下: QJsonDocument类提供了读写JSON文档的方法。QJsonDocument类包装了一个完整的JSON 文档,我们可以以utf-8编码的文本格式和Qt自己的二进制格式来操作该文档。一个JSON文档可以使用QJsonDocument::fromJson()函数转换json文本字符串来得到。而toJson()可以将其转换成文本。这个解析器是非常快速和高效的,Qt也是使用它来将JSON对象转换成其二进制表示的。解析得到的文档可以使用isNull()来判断是否有效。还可以使用isArray()和isObject()函数来判断该文档所包含的是否是数据或json对象。如果是,可以使用array()或object()函数还获得其中的对象或数组。 其构造函数如下:
QJsonDocument()
QJsonDocument(const QJsonObject &object)
QJsonDocument(const QJsonArray &array)
QJsonDocument(const QJsonDocument &other)
  除了构造函数外,该类还提供了两个转换函数,可以将json文档序列化为二进制对象,然后我们就可以将该对象存储到文件中,或发送到网络上。 
 
QByteArray toBinaryData() const
QByteArray toJson(JsonFormat format = Indented) const
  下面,我们就使用该类将我们上面生成的json数组写入到文件中: 
  代码如下: 
 
#include <QCoreApplication>
#include <QDebug>
#include <QJsonObject>
#include <QJsonArray>
#include <QFile>
#include <QJsonDocument>
int main(int argc, char *argv[])
    QCoreApplication a(argc, argv);
    QJsonObject obj1;
    obj1.insert("name", "lily");
    obj1.insert("age", 23);
    QJsonObject addr1;
    addr1.insert("city", "guangzhou");
    addr1.insert("province", "guangdong");
    obj1.insert("addr", addr1);
    qDebug() << obj1;
    QJsonObject obj2;
    obj2.insert("name", "tom");
    obj2.insert("age", 24);
    QJsonObject addr2;
    addr2.insert("city", "shenzhen");
    addr2.insert("province", "guangdong");
    obj2.insert("addr", addr2);
    qDebug() << obj2;
    QJsonObject obj3;
    obj3.insert("name", "jerry");
    obj3.insert("age", 24);
    QJsonObject addr3;
    addr3.insert("city", "foshan");
    addr3.insert("province", "guangdong");
    obj3.insert("addr", addr3);
    qDebug() << obj3;
    QJsonArray array;
    array.push_back(obj1);
    array.push_back(obj2);
    array.push_back(obj3);
    qDebug() << array;
    QJsonDocument jsonDoc(array);
    QByteArray ba = jsonDoc.toJson();
    QFile file("result.json");
    if(!file.open(QIODevice::WriteOnly))
        qDebug() << "write json file failed";
        return 0;
    file.write(ba);
    file.close();
    return a.exec();
我们先使用QJsonArray构建出一个QJsonDocument对象,然后调用其toJson()方法,将该json文档转换成一个字节数组。注意,toJson()函数会接受一个格式化参数:
QByteArray QJsonDocument::toJson(JsonFormat format = Indented) const
其中,format主要有两种格式,一种是人们可读的格式,一种是紧凑的格式。分别描述如下表:
ConstantValueDescription
QJsonDocument::Indented0定义人们可读的输出格式,如下:
{
"Array":[
true,
999,
"string"
],
"key": "value",
"null": null
}
QJsonDocument::Compact1定义一个紧凑的输出格式,如下:
{"Array": [true, 999, "string"], "key": "value", "null":null}

toJson()函数默认使用Indented,一缩进的形式生成人们可读的json文件。 运行该程序后,在编译目录查看生成的json文件。结果如下: 当然,除了将json对象写入到文件中,QJsonDocument还提供了几个静态函数,将从文件中读取出的原始数据或json字符串转换成一个QJsonDocument对象。函数声明信息如下:
QJsonDocument fromBinaryData(const QByteArray &data, DataValidation validation = Validate)
QJsonDocument fromJson(const QByteArray &json, QJsonParseError *error = Q_NULLPTR)
QJsonDocument fromRawData(const char *data, int size, DataValidation validation = Validate)
QJsonDocument fromVariant(const QVariant &variant)
  下面,我们就使用这些函数,将我们写入到文件中的json对象再读出来,并生成一个QJsonDocument对象。 
  代码如下: 
 
#include <QCoreApplication>
#include <QDebug>
#include <QFile>
#include <QJsonDocument>
int main(int argc, char *argv[])
    QCoreApplication a(argc, argv);
    QFile file("result.json");
    if(!file.open(QIODevice::ReadOnly))
        qDebug() << "read json file failed";
        return 0;
    QByteArray ba = file.readAll();
    qDebug() << "读出的数据如下:";
    qDebug() << ba;
    QJsonParseError e;
    QJsonDocument jsonDoc = QJsonDocument::fromJson(ba, &e);
    if(e.error == QJsonParseError::NoError && !jsonDoc.isNull())
        qDebug() << jsonDoc;
    return a.exec();
 
在此,因为我们从文件中读出的是一个json形式的字符串,所以可以使用fromJson()函数,将其转换成一个QJsonDocument对象。同时,在调用fromJson()函数时,我们还为它传入了一个QJsonParseError对象,用来接收解析json字符串的过程中,有可能发生的错误信息。 代码运行如下: JSON(JavaScript Object Notation,js对象标记)是一种轻量级的数据交换格式。它基于ECMAScript的一个子集,使用完全独立于编程语言的文本格式来存储和表示数据。简洁和清晰的的层次结构使得JSON成为理想的数据交换语言。易于人阅读和编写,同时也易于机器解析和生成,并有效的提升网络传输效率。关于JSON的更多解释,请参看JSON官网。
花了几天时间研究Qt如何操作Json文件,也是有一点心得,现在记录下来分享! 为什么要学习Json呢?Json是一个轻量级数据存储文件,其里面使用了大量的字符进行存储数据。JSON 是存储和交换文本信息的语法,类似 XML。JSON 比 XML 更小、更快,更易解析。 JSON 是一种编码来自 Javascript 的对象数据的格式,但现在已广泛用作互联网上的数据交换格式。 Qt JSON 支持提供了易于使用的C++ API 来解析、修改和保存 JSON 数据。 当然,我学习Json,主要是因为我的上
QJsonArray存储了一系列的QJsonValue。可以向其插入、删除QJsonValue。 一个QJsonArray可以与QVariantList互相转换。可以通过size()访问其的元素数,insert()、removeAt()移除其的元素,并通过标准C++迭代模式进行迭代。 QJsonArray是个隐含的共享类,它与创建该类的Json文档共享数据,也就是说修改数据时它们会同时改变。 可以从JSON生成QJsonArray或者把QJsonArray转化为JSON
//根据读取到的string创建json对象 private static JSONObject getJsonObject(String fileName) { JSONObject object = null; String jsonStr = getJsonStr(fileName); if (jsonStr != null) {
00. 目录 文章目录00. 目录01. QJsonObject类简介02. 公有类型03. 公有成员方法04. 公有成员方法解析05. 参考示例06. 附录 01. QJsonObject类简介 Header: #include <QJsonObject> qmake: QT += core Since: Qt 5.0 ​ QJsonObject类用于封装JSON对象。JSON对...
import java.text.ParseException; import org.json.JSONArray; import org.json.JSONObject; public class TestJsonArray {  public static void main(String[] args) throws ParseException {   String jsonS
JSON (JavaScript Object Notation) is a lightweight data-interchange format. JSON(JavaScript Object Notation)是一款轻量级的数据交换格式。 Part TWO. 建立JSON的Object 在Qt,用QJsonObject类定义Json对象。 通过初始化列表创建QJsonObject QJsonObject obj{ #include &lt;QCoreApplication&gt; #include &lt;QJsonObject&gt; #include &lt;QJsonArray&gt; #include &lt;QJsonDocument&gt; #include &lt;QDebug&gt; #include &lt;time.h&gt; int main(int argc...
JSONObject 的清除JSONObject 的清除.clear()方法:new JSONObject():null: JSONObject 的清除 原因:在循环内,亦或其它需要重复使用某json的情况下。 .clear()方法: ArrayList<JSONObject> item = new ArrayList<JSONObject>(); JSONObject sendAuth2 = new JSONObject(); sendAuth2
介绍:负责封装JSON对象,是键/值对列表,其键是惟一的字符串,值由QJsonValue表示。1——QJsonObjec:封装了Json里的对象接口与QMap相似,都具有size()、insert()和remove()等操作,还可以使用标准C++迭代器模式对其内容进行迭代。使用示例:如下图所示:我们要写入这个数据的话,怎么写进去? 记住一点就可以,[]前面的就是 Json数组格式,{}就是个Json对象格式2——QJsonArray: 封装了Json里的数组3——QJsonDocument:转换器 在这个示例,我们首先创建了一个QJsonObject对象,并添加了一些键值对。然后,我们使用QJsonDocument类将JSON对象转换为JSON文档。最后,我们使用toJson()函数将JSON文档转换为QByteArray类型。 注意:在使用QJsonDocument类时,需要包含头文件#include <QJsonDocument>。
lwei2: 好的,多谢楼主,第一点,发送信号个数受到QFileSystemWatcher的directoryChanged(QString)影响,一旦拷贝1000个照片到监控的目录,它会发送1000个信号给槽,在这个槽里,我定义了一个开启线程的信号,用线程获取文件信息,这个过程办法避免。第二点,我在线程处理完后发送更新的文件信息返回给QTableView,已在模型里开启定时器 void CustomTableModel::updateModel(QList<FileInfo> recordList) m_recordList = recordList; QTimer::singleShot(1000, this, [&](){ this->beginResetModel(); this->endResetModel(); }[code=cpp] [/code] 不过在更新到模型上的时间还是会卡,不知道是不是因为我给定时器太短时间了…… 使用QFileSystemWatcher监控磁盘文件状态变化 1.如果信号量很大,就不要在槽函数中做太重的操作了。 2.不要实时刷新,你既然使用的是view,肯定有相应的model,收到文件变化的信号后,把数据加到model里,不要立马update view,搭配定时器,周期性刷新试试呢 使用QFileSystemWatcher监控磁盘文件状态变化 lwei2: 楼主,请教一下:用QFileSystemWatcher监控某个目录,然后往监控的目录上拷贝1000个文件,一旦该监控目录发生变化了,就立刻向QTableView发送信号,并更新它在该监控目录上的文件变化,因为一下子发送的信号太多,连接的同一个槽函数,导致一下子界面卡住了,请问你有什么办法可以优化吗? Qt插件开发入门 买的挂什么时候到账: 博主,请问这个demo可以分享一下吗。想从代码中再学习。 QStorageInfo获取磁盘信息 -1 说明无法检测当前平台的最优磁盘块传输大小。磁盘分配单元是什么意思?扇区大小吗?