【Qt专栏】Qt中Json的使用教程

目录

前言

一,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自己的二进制格式来对该文档进行读写操作。
QJsonArrayJSON 数组是一个值的列表。可以通过从数组中插入和删除 QJsonValue 来操作该列表。
QJsonObjectJSON 对象是键值对的列表,其中键是唯一的字符串,值由 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();
                                                        }
                                                        //这里就不判断是否为其它类型了,因为测试文件已知为字符串,要写也和上面类似,无限套娃
                                                    }
                                                }
                                            }
                                        }
                                    }
                                    

                                    效果图如下