C 语言

关注公众号 jb51net

关闭
首页 > 软件编程 > C 语言 > Qt使用Json

Qt使用Json的项目实践

作者:小瑞的学习笔记

JSON是一种对源自Javascript的对象数据进行编码的格式,但现在被广泛用作互联网上的数据交换格式,本文主要介绍了Qt使用Json的项目实践,详细的介绍了主要使用的类以及Json实战,感兴趣的可以了解一下

JSON介绍

Qt支持处理JSON数据。JSON是一种对源自Javascript的对象数据进行编码的格式,但现在被广泛用作互联网上的数据交换格式。

Qt中的JSON支持提供了一个易于使用的C++API来解析、修改和保存JSON数据。它还支持以二进制格式保存数据,这种格式可以直接“mmap”,并且访问速度非常快。

主要使用的类

Json 类介绍
QJsonDocument它封装了一个完整的 JSON 文档,并且可以从 UTF-8 编码的基于文本的表示以及 Qt 自己的二进制格式读取和写入该文档。
QJsonArrayJSON 数组是一个值列表。可以通过从数组中插入和删除 QJsonValue 来操作该列表。
QJsonObjectJSON 对象是键值对的列表,其中键是唯一的字符串,值由 QJsonValue 表示。
QJsonValue该类封装了 JSON 支持的数据类型。

QJsonValue

在 Qt 中 QJsonValue 可以封装的基础数据类型有六种(和 Json 支持的类型一致),分别为:

这些类型可以通过 QJsonValue 的构造函数被封装为一个类对象:

// Json对象
QJsonValue(const QJsonObject &o);
// Json数组
QJsonValue(const QJsonArray &a);
// 字符串
QJsonValue(const char *s);
QJsonValue(QLatin1String s);
QJsonValue(const QString &s);
// 整形 and 浮点型
QJsonValue(qint64 v);
QJsonValue(int v);
QJsonValue(double v);
// 布尔类型
QJsonValue(bool b);
// 空值类型
QJsonValue(QJsonValue::Type type = Null);

如果我们得到一个 QJsonValue 对象,如何判断内部封装的到底是什么类型的数据呢?这时候就需要调用相关的判断函数了,具体如下:

// 是否是Json数组
bool isArray() const;
// 是否是Json对象
bool isObject() const;
// 是否是布尔类型
bool isBool() const;
// 是否是浮点类型(整形也是通过该函数判断)
bool isDouble() const;
// 是否是空值类型
bool isNull() const;
// 是否是字符串类型
bool isString() const;
// 是否是未定义类型(无法识别的类型)
bool isUndefined() const;

通过判断函数得到对象内部数据的实际类型之后,如果有需求就可以再次将其转换为对应的基础数据类型,对应的 API 函数如下:

// 转换为Json数组
QJsonArray toArray(const QJsonArray &defaultValue) const;
QJsonArray toArray() const;
// 转换为布尔类型
bool toBool(bool defaultValue = false) const;
// 转换为浮点类型
double toDouble(double defaultValue = 0) const;
// 转换为整形
int toInt(int defaultValue = 0) const;
// 转换为Json对象
QJsonObject toObject(const QJsonObject &defaultValue) const;
QJsonObject toObject() const;
// 转换为字符串类型
QString toString() const;
QString toString(const QString &defaultValue) const;

QJsonObject

QJsonObject 封装了 Json 中的对象,在里边可以存储多个键值对,为了方便操作,键值为字符串类型,值为 QJsonValue 类型。

QJsonObject::QJsonObject();	// 构造空对象
iterator QJsonObject::insert(const QString &key, const QJsonValue &value);
int QJsonObject::count() const;
int QJsonObject::size() const;
int QJsonObject::length() const;
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;
void QJsonObject::remove(const QString &key);
QJsonValue QJsonObject::take(const QString &key);	// 返回key对应的value值
iterator QJsonObject::find(const QString &key);
bool QJsonObject::contains(const QString &key) const;

遍历,方式有三种:

QStringList QJsonObject::keys() const;

QJsonDocument

下面依次介绍一下这两个转换流程应该如何操作:

1. QJsonObject 或者 QJsonArray ===> 字符串

QJsonDocument::QJsonDocument(const QJsonObject &object);
QJsonDocument::QJsonDocument(const QJsonArray &array);

可以看出,通过构造函数就可以将实例化之后的 QJsonObject 或者 QJsonArray 转换为 QJsonDocument 对象了。

// 二进制格式的json字符串
QByteArray QJsonDocument::toBinaryData() const;	 
// 文本格式
QByteArray QJsonDocument::toJson(JsonFormat format = Indented) const;

通过调用 toxxx() 方法就可以得到文本格式或者二进制格式的 Json 字符串了。

2. 字符串 ===> QJsonObject 或者 QJsonArray

一般情况下,通过网络通信或者读磁盘文件就会得到一个 Json 格式的字符串,如果想要得到相关的原始数据就需要对字符串中的数据进行解析,具体解析流程如下:

[static] QJsonDocument QJsonDocument::fromBinaryData(const QByteArray &data, DataValidation validation = Validate);
// 参数文件格式的json字符串
[static] QJsonDocument QJsonDocument::fromJson(const QByteArray &json, QJsonParseError *error = Q_NULLPTR);
// 判断文档对象中存储的数据是不是数组
bool QJsonDocument::isArray() const;
// 判断文档对象中存储的数据是不是json对象
bool QJsonDocument::isObject() const
// 文档对象中的数据转换为json对象
QJsonObject QJsonDocument::object() const;
// 文档对象中的数据转换为json数组
QJsonArray QJsonDocument::array() const;

关于 Qt 中 Json 数据对象以及字符串之间的转换的操作流程是固定的,我们在编码过程中只需要按照上述模板处理即可,相关的操作是没有太多的技术含量可言的。

实战

1. 手动写Json文件

注意:[…] 中是数组元素,{…}中是Json对象

在这里插入图片描述

2. 实现程序(从Json文件中读取数据,更改Json文件中的数据)

mainwindow.h

class MainWindow : public QMainWindow
{
    Q_OBJECT
public:
    explicit MainWindow(QWidget *parent = 0);
    ~MainWindow();
    QVector<struct Animal> readJson();// 读取Json文件
    bool changeDate();// 改变Json文件中的数据
private:
    Ui::MainWindow *ui;
};
struct Food{
    QString stapleFood;
    QString meat;
};
struct Animal{
    QString name;
    int age;
    QVector<QString> eatTimeArr;
    struct Food food;
};

mainwindow.cpp

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    changeDate();
    readJson();
}
MainWindow::~MainWindow()
{
    delete ui;
}
// 增加数据直接在手动修改Json文件
// 查数据(已知Json数据格式的情况下):将Json中所有animal类保存到vector中全部返回
QVector<struct Animal> MainWindow::readJson()
{
    QFile file("D:\\Qt\\homework\\text01\\studyJson.json");
    bool ret = file.open(QFile::ReadOnly);
    QByteArray bytes = file.readAll();// 把文件中所有数据读取出来
    QJsonDocument doc = QJsonDocument::fromJson(bytes);// 将读出的数据保存为Json文档
    QJsonArray groupArr = doc.array();// 获取数组
    QVector<struct Animal> ans;// 用于保存获取到的数据
   for(int i = 0; i < groupArr.size(); i++)
   {
       QJsonObject obj = groupArr.at(i).toObject();// 把数组中每一个数据都转化为 QJsonObject
       struct Animal animal;
       animal.name = obj.value("name").toString();
       animal.age = obj.value("age").toInt();
       // eatTime 对应的值为一个数组
       QJsonArray foodArr = obj.value("eatTime").toArray();
       for(int i = 0; i < foodArr.size(); i++)
       {
           animal.eatTimeArr.push_back(foodArr.at(i).toString());
       }
       // food 对应的值为一个 QJsonObject 类型
       QJsonObject subObj = obj.value("food").toObject();
       animal.food.stapleFood = subObj.value("stapleFood").toString();
       animal.food.meat = subObj.value("meat").toString();
       ans.push_back(animal);// 将获取到的数据加入容器中
       qDebug() << "name =" << animal.name
                << "age =" << animal.age
                << "eatTime =" << animal.eatTimeArr[0] << animal.eatTimeArr[1] << animal.eatTimeArr[2]
                << "food.stapleFood =" << animal.food.stapleFood
                << "food.meat =" << animal.food.meat;
   }
   return ans;
}
// 改数据:从studyJson.json读取数据并且富贵的年龄改为10岁
bool MainWindow::changeDate()
{
    // 打开文件
    QFile file("D:\\Qt\\homework\\text01\\studyJson.json");
    file.open(QIODevice::ReadWrite);
    QByteArray bytes = file.readAll();// 读取文件所有内容
    file.close();
    QJsonDocument doc = QJsonDocument::fromJson(bytes);// 将读出的数据保存为Json文档
    QJsonArray groupArr = doc.array();// 获取数组
    QJsonObject obj = groupArr.at(0).toObject();// 获取数组中第一个元素
    // 判断 "age"节点是否存在
    if(obj.contains("age")){
        obj["age"] = 10;// 将数组第一个元素中的年龄改变
        // 此时我们新建一个数组,把更新好的元素加入数组,并且把之前数组中没有改变的元素加入
        QJsonArray arr;
        arr.append(obj);
        arr.append(groupArr.at(1).toObject());
        // 保存至Json文档  注意:调用setArray后,先会把之前保存所有的数据清除,然后再保存新的数据
        doc.setArray(arr);
    }
    // 把最新数据写入QIODevice::Truncate
    file.open(QFile::WriteOnly|QFile::Truncate);
    file.seek(0);// 使写入位置为起始位置
    file.write(doc.toJson());
}

打印调试信息

在这里插入图片描述

执行changeDate()后,Json文件改变

这里需要注意:如果用Json自己写入文件,他所有数据会根据key的字典序排列

在这里插入图片描述

到此这篇关于Qt使用Json的项目实践的文章就介绍到这了,更多相关Qt使用Json内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:
阅读全文