Qt解析Json数据

news2024/11/30 8:55:06

目录

      • 前言
      • 1.下载 jsoncpp 源码
      • 2.编译
      • 3.JSON数据读写示例
      • 4.jsoncpp核心类详解

前言

本文主要介绍了使用Qt框架编程时如何解析JSON数据的一种方法。JSON是英文JavaScript Object Notation 的缩写,它是一种轻量级的数据交换格式,具有方便阅读和编写的优点,同时也易于机器解析和生成。JSON数据格式应用广泛,能够用于多种语言之间的数据交换。当前开源的C++JSON解析库有大概几十种,比较著名的有jsoncpp、nlohmann/json、rapidjson、jsonxx等。除此之外Qt5.0以上的版本也提供了JSON数据的读写支持。本文以jsoncpp库为例介绍如何使用第三方库实现JSON数据的读写。

1.下载 jsoncpp 源码

点击下载地址打开如下如所示页面,下载jsoncpp源码。
在这里插入图片描述

2.编译

按照国际惯例,这里使用Cmake来编译jsoncpp动态库。笔者是在Win10系统下编译的,首先打开cmake-gui,然后选择下载的jsoncpp源码路径,并设置好编译目录。如下图所示
在这里插入图片描述
依次点击 Configure、Generate、Open Project 按钮,打开生成的VS工程。
在这里插入图片描述
在解决方案上右键弹出菜单,选择【批生成】菜单项,在弹出的页面中勾选 “ALL_BUILD Debug"和"ALL_BUILD Release” ,如图所示
在这里插入图片描述
点击生成按钮,等待编译完成,查看是否生成对应的动态库文件。这种批生成其实也生成了对应debug和release版本的静态库。生成结束后打开build目录中的lib文件夹,可以看到Debug和Release两个目录。打开其中一个可以看到如下图所示内容
在这里插入图片描述

3.JSON数据读写示例

新建一个带界面的QT应用程序,把编译好的动态库引入到工程中。在pro文件中添加如下代码

INCLUDEPATH += $$PWD/include

CONFIG(debug) {
    message(debug mode)
    LIBS += -L$$PWD/lib -ljsoncppd
} else {
    message(release mode)
    LIBS += -L$$PWD/lib -ljsoncpp
}

DESTDIR = $$PWD/bin

其中include 目录中包含jsoncpp的头文件,lib目录下是jsoncpp动态库lib文件。并将对应的dll 文件拷贝到bin目录下。目录结构如下图所示
在这里插入图片描述

简单的创建一个界面来完成json数据的读写操作,UI如下图所示,左侧是一个用户信息表,右边是添加用户信息的页面。在输入框中输入用户信息,点击保存按钮新增用户信息,并把用户信息以JSON格式保存到文件中。点击刷新按钮,把文件中所有的用户信息读取到表格中。
在这里插入图片描述
保存按钮的槽函数为slot_saveUserInfo()。 writeDataToFile()函数将用户信息转为json数据格式,并写入到bin目录下的userList.json文件中。

void MainWindow::slot_saveUserInfo()
{
    UserInfo userInfo;
    userInfo.name = ui->le_name->text().trimmed();
    userInfo.phone = ui->le_no->text().trimmed();
    userInfo.address = ui->le_address->text().trimmed();

    m_userList.append(userInfo);

    writeDataToFile();
}


void MainWindow::writeDataToFile()
{
    QString jsonFileName = qApp->applicationDirPath() + "/userList.json";

    Json::Value userListVal;
    for (int i = 0; i < m_userList.size(); i++)
    {
        Json::Value userInfo;
        userInfo["name"] = m_userList[i].name.toLocal8Bit().data();
        userInfo["phone"] = m_userList[i].phone.toLocal8Bit().data();
        userInfo["address"] = m_userList[i].address.toLocal8Bit().data();

        userListVal.append(userInfo);
    }

    Json::Value jsonRoot;
    jsonRoot["userList"] = userListVal;

    Json::StyledWriter writer;
    std::string jsonData = writer.write(jsonRoot);

    printf("jsonData:\n %s ", jsonData.c_str());

    QFile jsonFile(jsonFileName);
    if (jsonFile.open(QIODevice::WriteOnly))
    {
        qint64 nRet = jsonFile.write(jsonData.c_str());
        if (nRet < 0)
        {
            qDebug() << "write data failed!";
        }
        jsonFile.close();
    }
}

在页面上添加几条数据,查看userList.json文件内容,由于编码问题,中文是以Unicode编码的形式保存的。

{
   "userList" : [
      {
         "address" : "\u5317\u4eac\u5e02\u6d77\u6dc0\u533a\u5f20\u5bb6\u6c9f\u6751",
         "name" : "\u5f20\u4e09",
         "phone" : "18078665544"
      },
      {
         "address" : "\u5317\u4eac\u5e02\u6d77\u6dc0\u533a\u674e\u5bb6\u6c9f\u6751",
         "name" : "\u674e\u56db",
         "phone" : "18078665599"
      }
   ]
}

点击刷新按钮,将文件中的数据,读取到页面的列表中。刷新按钮的响应函数是slot_refreshUserTable(),代码如下

void MainWindow::slot_refreshUserTable()
{
    QString jsonFileName = qApp->applicationDirPath() + "/userList.json";

    QFile jsonDataFile(jsonFileName);
    if (jsonDataFile.open(QIODevice::ReadOnly))
    {
        std::string jsonStr = jsonDataFile.readAll().data();
        Json::Value jsonRoot;
        Json::Reader reader;
        if (reader.parse(jsonStr, jsonRoot))
        {

            Json::Value userListVal = jsonRoot["userList"];
            if (userListVal.isArray())
            {
                Json::Value::iterator iter = userListVal.begin();
                m_userList.clear();
                while (iter != userListVal.end())
                {
                    Json::Value userInfo = userListVal[iter.index()];

                    UserInfo stUserInfo;
                    stUserInfo.name = userInfo.get("name", "").asCString();
                    stUserInfo.phone = userInfo.get("phone", "").asCString();
                    stUserInfo.address = userInfo.get("address", "").asCString();
                    m_userList.append(stUserInfo);

                    iter++;
                }

                updateTableWidget();
            }
        }
    }
}

页面显示效果
在这里插入图片描述

4.jsoncpp核心类详解

从上面的示例中,可以看到jsoncpp使用起来非常便捷,其核心类为Json::Value 、Json::StyledWriter、Json::Reader。其中Json为命名空间。

  • Value
    该类是泛型数据表示类,json格式支持的各种数据类型都可以用这个类来存储,并能在使用时转换成实际的数据类型。下面的枚举ValueType 描述了Value类支持的所有数据类型。
		enum ValueType {
		  nullValue = 0, ///< 'null' value
		  intValue,      ///< signed integer value
		  uintValue,     ///< unsigned integer value
		  realValue,     ///< double value
		  stringValue,   ///< UTF-8 string value
		  booleanValue,  ///< bool value
		  arrayValue,    ///< array value (ordered list)
		  objectValue    ///< object value (collection of name/value pairs).
		};

Value的赋值

	Json::Value userListVal; //arrayValue 类型
    for (int i = 0; i < m_userList.size(); i++)
    {
        Json::Value userInfo; //objectValue 类型,直接通过下标赋值
        userInfo["name"] = m_userList[i].name.toLocal8Bit().data();
        userInfo["phone"] = m_userList[i].phone.toLocal8Bit().data();
        userInfo["address"] = m_userList[i].address.toLocal8Bit().data();

        userListVal.append(userInfo); //arrayValue 类型添加数据
    }

Value类型判断,通过调用Value提供的一组API可以轻松的辨别数据的具体类型。

  bool isNull() const;
  bool isBool() const;
  bool isInt() const;
  bool isInt64() const;
  bool isUInt() const;
  bool isUInt64() const;
  bool isIntegral() const;
  bool isDouble() const;
  bool isNumeric() const;
  bool isString() const;
  bool isArray() const;
  bool isObject() const;

Value类型转换, 通过下面的API可以将Value转换成实际数据类型的数据。

  String asString() const; 
  Int asInt() const;
  UInt asUInt() const;
#if defined(JSON_HAS_INT64)
  Int64 asInt64() const;
  UInt64 asUInt64() const;
#endif // if defined(JSON_HAS_INT64)
  LargestInt asLargestInt() const;
  LargestUInt asLargestUInt() const;
  float asFloat() const;
  double asDouble() const;
  bool asBool() const;
  • StyledWriter
    StyledWriter 类能够把Json::Value组织起来的数据,转换成JSON格式的字符串。这个类有两个兄弟类 Writer。StyledWriter与Writer的区别是StyledWriter类输出的JSON字符串含有换行符,易于阅读,而Writer输出的JSON字符串就是一行数据,中间没有换行符。StyledWriter和Writer类的使用也很简单,直接调用write函数就好了!
	Json::StyledWriter writer;
    std::string jsonData = writer.write(jsonRoot);
  • Reader
    Reader类的功能是把JSON格式的字符串数据转换成Json::Value存储的数据。程序中再根据Json::Value的具体类型使用这些数据。Reader类的用法也非常简单。
 		std::string jsonStr = jsonDataFile.readAll().data();
        Json::Value jsonRoot;
        Json::Reader reader;
        if (reader.parse(jsonStr, jsonRoot))
        {
        	//正确解析,DoSomthing
		}

以上就是本文的所有内容,如有疑问欢迎您留言讨论。本文demo下载地址

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/152376.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Jenkins 项目的 gpg: signing failed: Bad passphrase 错误

因为我们项目需要使用 Jenkins 对文件进行签名。但是我们遇到了gpg: signing failed: Bad passphrase错误。原因和解决通常这个问题的原因是 Key 已经配置成功并且已经被命令行找到了。主要原因是你的秘钥密码配置的问题。这个配置有 2 个地方&#xff0c;第一个地方是项目的 P…

2022年度牛奶乳品行业数据:十大热门品牌销量排行榜

当前&#xff0c;随着经济的发展及人民生活水平的提高&#xff0c;牛奶乳品已经日趋成为人们在日常饮食中不可缺少的食物之一&#xff0c;市面上的产品种类也越来越多。并且&#xff0c;随着人们消费习惯的转变&#xff0c;牛奶乳品的消费场景也日益多元化。未来&#xff0c;预…

jdk1.8之函数式接口

l[TOC] 函数式接口概述 jdk1.8 引入了一个核心概念&#xff1a;函数式接口&#xff08;Functional Interface&#xff09;。如果一个接口有且只有一个未实现的方法&#xff0c;那这个接口就称为函数式接口。并且引入了一个新的注解&#xff1a;FunctionalInterface &#xff0…

一、Gradle入门

文章目录一、Gradle入门1.1 Gradle 简介1.2 常见的项目构建工具1.3 Gradle 安装1.3.1 Gradle 安装说明1.3.2 安装 JDK1.3.3 下载并解压到指定目录1.3.4 配置环境变量1.3.5 检测是否安装成功1.4 Gradle 项目目录结构1.5 Gradle 创建第一个项目1.5.1 Gradle 中的常用命令1.5.2 修…

【MySQL进阶教程】视图/存储过程/触发器

前言 本文为 【MySQL进阶教程】视图/存储过程/触发器 相关知识&#xff0c;下边将对视图&#xff0c;存储过程&#xff0c;存储函数&#xff0c;触发器等进行详尽介绍~ &#x1f4cc;博主主页&#xff1a;小新要变强 的主页 &#x1f449;Java全栈学习路线可参考&#xff1a;【…

MySQL高级【存储函数触发器】

1&#xff1a;存储函数1.1&#xff1a;介绍存储函数是有返回值的存储过程&#xff0c;存储函数的参数只能是IN类型的。具体语法如下&#xff1a; CREATE FUNCTION 存储函数名称 ([ 参数列表 ]) RETURNS type [characteristic ...] BEGIN -- SQL语句 RETURN ...; END ;character…

如何管理存量用户?

存量市场的老客户对于企业来说如同一座金矿&#xff0c;好好运营老客户&#xff0c;可以给企业带来源源不断的新客户&#xff0c;企业所获得的收益远比拉新所获收益要高的多。 前言 存量客户是指某个时间段里原先已有的客户&#xff0c;与新增客户相对应&#xff0c;通俗点说&…

Python开发Web扫描器实战

今天继续给大家介绍渗透测试相关知识&#xff0c;本文主要内容是Python开发Web扫描器实战。 免责声明&#xff1a; 本文所介绍的内容仅做学习交流使用&#xff0c;严禁利用文中技术进行非法行为&#xff0c;否则造成一切严重后果自负&#xff01; 再次强调&#xff1a;严禁对未…

机器学习--模型评估、过拟合和欠拟合、模型验证

目录 一、模型评估 模型指标 常见关于分类的指标 准确率 精确率(精确度) 召回率 F1 score PR曲线&#xff1a; ROC AUC 二、过拟合和欠拟合 训练与泛化误差的区别 什么样的情况会导致欠拟合与过拟合&#xff1f; 模型的复杂度&#xff08;能够拟合各种各样函…

分组加密模式 ECB CBC OFB CFB

多个分组加密互相之间如何关联 ECB模式 每个分组之间单独加密&#xff0c;互不关联 2个分组明文一样&#xff0c;结果也一样&#xff0c;那么只需爆破其中1个就可以了 每个分组互不关联&#xff0c;可以分段同时来爆破&#xff0c;不安全 可以通过替换某段密文来达到替换明…

11.Isaac教程--在docker中模拟训练姿势估计模型

在docker中模拟训练姿势估计模型 文章目录在docker中模拟训练姿势估计模型怎么运行的主机设置硬件要求软件要求NGC Docker 注册表设置第一次运行数据集生成配置您的工作区Jupyter 变量设置开始训练添加您自己的 3D 模型故障排除接下来物体检测和 3D 姿态估计在机器人技术中起着…

『精』EditorConfig 小老鼠 跨编辑器 | IDE 保持一致的编码风格

『精』EditorConfig 小老鼠 跨编辑器 | IDE 保持一致的编码风格 文章目录『精』EditorConfig 小老鼠 跨编辑器 | IDE 保持一致的编码风格一、什么是EditorConfig二、文件识别符三、风格属性控制四、不同规则参考1)、简洁通用2)、前端Vue项目3)、前端React项目4)、前端Angular项…

Linux常用命令——nm命令

在线Linux命令查询工具(http://www.lzltool.com/LinuxCommand) nm 显示二进制目标文件的符号表 补充说明 nm命令被用于显示二进制目标文件的符号表。 语法 nm(选项)(参数)选项 -A&#xff1a;每个符号前显示文件名&#xff1b; -D&#xff1a;显示动态符号&#xff1b; …

成员变量-java循环机构

1.概念所谓的成员变量&#xff0c;是指在类中(不是方法或其他代码块)直接定义的变量。根据是否带有static关键字&#xff0c;成员变量又分为静态变量(类变量)、实例变量(对象变量)。成员变量在整个类的内部都有效&#xff0c;可以在当前类的任何方法中使用。另外如果成员变量不…

NFS介绍及服务器搭建

一、NFS 简介 NFS&#xff0c;英文全称 Network File System&#xff0c;主要功能&#xff1a;通过网络&#xff0c;让不同的机器、不同的操作系统可以共享文件。类似windows的共享文件夹 ​ NFS服务器共享本机目录&#xff0c;客户端机器挂载该目录后&#xff0c;就可以像自…

AI+OCR赋能古彝文数字化—让经典重新跳动

1️⃣ 彝文与古彝文概况文化是一个民族社会历史发展到一定程度的产物&#xff0c;代表着文明发展的程度&#xff0c;而文字是文化的一种载体&#xff0c;文字的出现是社会进入文明阶段的重要标志之一&#xff0c;其生动记录着一个民族的智慧成果&#xff0c;深刻反映着一个民族…

Unity 3D 环境特效||Unity 3D 游戏场景设计实例

Unity 3D 环境特效 一般情况下&#xff0c;要在游戏场景中添加雾特效和水特效较为困难&#xff0c;因为需要开发人员懂得着色器语言且能够熟练地使用它进行编程。 Unity 3D 游戏开发引擎为了能够简单地还原真实世界中的场景&#xff0c;其中内置了雾特效并在标准资源包中添加…

mmLab系列使用方法

mmLab系列使用方法环境搭建mmdetection检查数据集运行部署mmdeploy环境搭建使用mmOCRmmsegmentation环境搭建 Windows最推荐安装方法&#xff1a; 首先需要查好自己gpu的CUDA版本&#xff0c;根据版本到pytorch官方网站查找对应的pytorch版本(!!!只查找不下载&#xff01;)ht…

Mybatis源码分析(七)MapperMethod的INSERT分析

目录一 INSERT 语句1.1 参数的对应解析convertArgsToSqlCommandParam1.2 ID获取对应的MappedStatement1.3 MappedStatement交给执行器执行1.4 不同的执行器获取不同的StatementHandler1.5 根据参数获取BoundSql1.6 执行器配置参数处理器ParameterHandler1.7 拿到StatementHandl…

人工智能-http协议和静态服务器

目录1、HTTP协议1.1 网址1.2 http协议的介绍1.3 http请求报文1.&#xff14; http响应报文1.&#xff15;查看http协议的通信过程&#xff12;、静态web服务器程序开发2.1 搭建python自带的静态web服务器2.2 静态web服务器-返回固定页面数据1、HTTP协议 1.1 网址 网站又称为U…