C++学习之路(九)C++ 用Qt5实现一个工具箱(增加一个JSON数据格式化功能)- 示例代码拆分讲解

news2024/11/9 5:17:47

上篇文章,我们用 Qt5 实现了在小工具箱中添加了《粘贴板记录管理》功能,用着还不错哈。为了继续丰富我们的工具箱,今天我们就再增加一个平时经常用到的功能吧,就是「 JSON数据格式化 」功能。下面我们就来看看如何来规划开发一个这样的小功能并且添加到我们的工具箱中吧。

老规矩,先看效果

在这里插入图片描述

功能规划

这个JSON格式化功能是工具箱的一部分,它允许用户输入JSON数据并对其进行格式化排版。主要功能包括:

  1. JSON数据格式化: 用户可以在文本框中输入或粘贴JSON格式的数据。
  2. 格式化按钮: 点击“格式化JSON”按钮后,程序会尝试解析用户输入的JSON数据。如果数据有效,它会重新排列和缩进JSON数据,使其结构更清晰、易读。
  3. 错误处理: 如果JSON数据无效(格式错误),程序会弹出警告消息框提示用户错误的具体信息,让用户知晓数据存在问题。
    在这里插入图片描述

这个功能对于需要处理JSON数据的开发者或用户来说非常实用,它能够帮助他们快速查看和理解JSON数据的结构和内容,减少了手动排版的工作,提高了效率。

看完介绍就直接上代码

#include <QApplication>
#include <QWidget>
#include <QPushButton>
#include <QVBoxLayout>
#include <QMessageBox>
#include <QDebug>
#include <QListWidget>
#include <QClipboard>
#include <QMimeData>
#include <QTextEdit>
#include <QJsonDocument>
#include <QJsonObject>

#define myApp (dynamic_cast<QApplication *>(QCoreApplication::instance()))

class JsonFormatter : public QWidget {
Q_OBJECT
public:
    explicit JsonFormatter(QWidget *parent = nullptr) : QWidget(parent) {
        auto *layout = new QVBoxLayout(this);

        inputTextEdit = new QTextEdit(this);
        layout->addWidget(inputTextEdit);

        formatButton = new QPushButton("格式化", this);
        connect(formatButton, &QPushButton::clicked, this, &JsonFormatter::formatJson);
        layout->addWidget(formatButton);

        outputTextEdit = new QTextEdit(this);
        outputTextEdit->setReadOnly(true);
        layout->addWidget(outputTextEdit);

        setLayout(layout);
    }

private slots:
    void formatJson() {
        QString inputText = inputTextEdit->toPlainText();
        QJsonParseError error{};
        QJsonDocument jsonDoc = QJsonDocument::fromJson(inputText.toUtf8(), &error);

        if (error.error != QJsonParseError::NoError) {
            outputTextEdit->setText("JSON 解析错误:" + error.errorString());
            return;
        }

        QJsonObject jsonObj = jsonDoc.object();
        QJsonDocument formattedJson(jsonObj);

        outputTextEdit->setText(formattedJson.toJson());
    }

private:
    QTextEdit *inputTextEdit;
    QPushButton *formatButton;
    QTextEdit *outputTextEdit;
};

class ClipboardManager : public QWidget {
Q_OBJECT
public:
    explicit ClipboardManager(QWidget *parent = nullptr) : QWidget(parent) {
        auto *layout = new QVBoxLayout(this);

        listWidget = new QListWidget(this);
        updateList(); // 初始更新列表

        auto *clearButton = new QPushButton("清空记录", this);
        connect(clearButton, &QPushButton::clicked, this, &ClipboardManager::clearClipboard);

        layout->addWidget(listWidget);
        layout->addWidget(clearButton);

        setLayout(layout);

        connect(myApp->clipboard(), &QClipboard::dataChanged, this, &ClipboardManager::updateList);
    }

private slots:
    void updateList() {
        const QClipboard *clipboard = myApp->clipboard();
        const QMimeData *mimeData = clipboard->mimeData();

        if (mimeData->hasText()) {
            const QString clipboardText = mimeData->text();

            if (!clipboardText.isEmpty()) {
                listWidget->addItem(clipboardText);
            }
        }
    }

    void clearClipboard() {
        myApp->clipboard()->clear();
        listWidget->clear();
    }

private:
    QListWidget *listWidget;
};

class MyMainWindow : public QWidget {
Q_OBJECT
public:
    explicit MyMainWindow(QWidget *parent = nullptr) : QWidget(parent) {
        setWindowTitle("天河工具箱");

        auto *layout = new QVBoxLayout(this);

        auto *clipboardButton = new QPushButton("管理粘贴板记录");
        connect(clipboardButton, &QPushButton::clicked, this, &MyMainWindow::toggleClipboardManager);
        clipboardManager = new ClipboardManager(this);
        clipboardManager->hide();
        layout->addWidget(clipboardManager);
        layout->addWidget(clipboardButton);

        auto *jsonFormatButton = new QPushButton("格式化 JSON");
        connect(jsonFormatButton, &QPushButton::clicked, this, &MyMainWindow::toggleJsonFormatter);
        jsonFormatter = new JsonFormatter(this);
        jsonFormatter->hide();
        layout->addWidget(jsonFormatter);
        layout->addWidget(jsonFormatButton);

        setLayout(layout);
    }

private slots:

    void toggleClipboardManager() {
        if (clipboardManager->isHidden()) {
            clipboardManager->show();
        } else {
            clipboardManager->hide();
        }
    }

    void toggleJsonFormatter() {
        if (jsonFormatter->isHidden()) {
            jsonFormatter->show();
        } else {
            jsonFormatter->hide();
        }
    }

private:
    ClipboardManager *clipboardManager;
    JsonFormatter *jsonFormatter;
};

int main(int argc, char *argv[]) {
    QApplication a(argc, argv);

    MyMainWindow mainWindow;
    mainWindow.show();

    return QApplication::exec();
}

#include "main.moc"

看完代码了吗?

看完了我们就开始拆分讲解一下JSON数据格式化的功能吧,还有我们用到的相关知识点,最后我们再来一些注意事项就算完成任务了~

先从整体来拆解,看一下我们的代码。代码包含了两个自定义的小部件类:JsonFormatterClipboardManager。它们被整合到了 MyMainWindow 中,提供了管理粘贴板记录和JSON格式化的功能。

JsonFormatter 类

这个类用于实现 JSON 格式化的功能。它包含了两个文本框和一个按钮,按钮用于触发格式化操作。主要功能有:

  • 构造函数: 创建了界面所需的部件,并设置了布局。
  • formatJson 函数(槽函数): 当格式化按钮被点击时,该函数将尝试解析输入文本框中的 JSON 数据。如果解析成功,它会对 JSON 数据进行格式化,并将格式化后的结果显示在输出文本框中。

ClipboardManager 类

这个类用于管理粘贴板记录。它包含了一个列表部件和一个按钮,按钮用于清空记录。主要功能有:

  • 构造函数: 创建了界面所需的部件,并设置了布局。
  • updateList 函数(槽函数): 当剪贴板的数据发生变化时,该函数会更新粘贴板记录列表。它会获取剪贴板中的文本数据,并将非空文本添加到记录列表中。
  • clearClipboard 函数(槽函数): 当清空记录按钮被点击时,该函数会清空粘贴板的内容,并清空记录列表。

MyMainWindow 类

这个类是主窗口类,整合了 ClipboardManagerJsonFormatter 类的功能,并提供了按钮用于切换这两个功能的显示和隐藏。

主函数

在主函数中,创建了 QApplication 对象,并实例化了 MyMainWindow 类作为应用的主窗口,最后通过 QApplication::exec() 运行应用。

这些类结合了 Qt 的布局管理器和信号槽机制,提供了简单而有效的用户界面,并为用户提供了管理粘贴板和JSON格式化的功能。


下面就着重讲解今天的主角 JsonFormatter 类

让我们来仔细看一下 JsonFormatter 类的代码,并分段进行介绍讲解。

头文件
#include <QWidget>
#include <QPushButton>
#include <QVBoxLayout>
#include <QTextEdit>
#include <QJsonDocument>
#include <QJsonObject>

JsonFormatter 类用到了 QWidgetQPushButtonQVBoxLayoutQTextEditQJsonDocumentQJsonObject 等 Qt 的头文件,用于界面构建和 JSON 数据处理。

  • QWidget:Qt 中用于构建用户界面的基类。JsonFormatter 类继承自 QWidget,用于创建 JSON 格式化功能的界面部件。

  • QPushButton:Qt 中的按钮部件类,用于创建按钮控件。在 JsonFormatter 中使用了按钮来触发 JSON 格式化操作。

  • QVBoxLayout:Qt 中的垂直布局管理器,用于在窗口中垂直地排列部件。在 JsonFormatter 类的构造函数中使用了该布局来安排按钮和文本框的位置。

  • QTextEdit:Qt 中用于显示和编辑文本的控件。JsonFormatter 类中的输入和输出文本框均基于 QTextEdit 实现。

  • QJsonDocumentQJsonObject:Qt 提供的用于处理 JSON 数据的类。QJsonDocument 用于处理 JSON 文档,QJsonObject 用于表示 JSON 对象。在 JsonFormatter 类的 formatJson() 函数中使用这两个类来解析和处理 JSON 数据。

这些头文件提供了构建用户界面、创建按钮、设置布局以及处理和解析 JSON 数据所需的类和函数。它们为 JsonFormatter 类的实现提供了界面创建和 JSON 数据处理的基础功能。

类定义
class JsonFormatter : public QWidget {
    Q_OBJECT
public:
    explicit JsonFormatter(QWidget *parent = nullptr) : QWidget(parent) {
        // ...
    }

private slots:
    void formatJson() {
        // ...
    }

private:
    QTextEdit *inputTextEdit;
    QPushButton *formatButton;
    QTextEdit *outputTextEdit;
};
  • JsonFormatter 类继承自 QWidget,用于创建 JSON 格式化功能的界面部件。
  • 构造函数 JsonFormatter(QWidget *parent = nullptr):创建了 JSON 格式化功能所需的文本框、按钮和布局,初始化界面。
  • formatJson() 函数(槽函数):用于处理格式化按钮的点击事件,将输入的 JSON 数据格式化,并在输出文本框中显示。
格式化 JSON 数据
void formatJson() {
    QString inputText = inputTextEdit->toPlainText();
    QJsonParseError error{};
    QJsonDocument jsonDoc = QJsonDocument::fromJson(inputText.toUtf8(), &error);

    if (error.error != QJsonParseError::NoError) {
        outputTextEdit->setText("JSON 解析错误:" + error.errorString());
        return;
    }

    QJsonObject jsonObj = jsonDoc.object();
    QJsonDocument formattedJson(jsonObj);

    outputTextEdit->setText(formattedJson.toJson());
}
  • 获取输入文本框中的文本,并尝试将其解析为 JSON 格式的数据。
  • 使用 QJsonDocument::fromJson() 解析 JSON 数据,若解析失败则会设置 QJsonParseError,并在输出文本框中显示解析错误信息。
  • 如果解析成功,将解析后的 JSON 对象重新构建为 QJsonDocument,并使用 toJson() 方法将其格式化后的内容显示在输出文本框中。

总结

JsonFormatter 类利用 Qt 提供的 JSON 处理能力和界面构建功能,实现了简单的 JSON 格式化功能。它通过界面上的按钮触发格式化操作,将用户输入的 JSON 数据解析并重新排版显示,方便用户查看和理解 JSON 数据的结构和内容。

最后,在上面示例中,我们需要注意哪些地方?

JsonFormatter 示例中,有几个方面需要注意:

  1. 错误处理: 在解析 JSON 数据时,通过 QJsonParseError 进行错误检查,如果 JSON 格式错误,会在输出文本框中显示错误信息。这是一个很好的实践,能够向用户传达解析问题。

  2. 用户输入验证: 目前的代码并未对用户输入进行详细的验证,如果需要更严格的输入检查,可以添加额外的逻辑以确保输入数据的准确性和完整性。

  3. 界面交互性: 输入文本框与输出文本框的界面交互性有限。可以考虑在解析前对输入进行格式预处理、高亮显示错误部分或者给出更详细的错误信息。

  4. 使用 QJsonDocument 和 QJsonObject: 这两个类提供了方便的 JSON 数据处理方法。在实际项目中,可以进一步了解其功能,例如遍历 JSON 结构、修改数据等操作。(链接中是对应的文档地址)

  5. 错误处理和异常情况: 在解析 JSON 时,需要注意可能出现的异常情况,并在代码中进行适当的处理,确保程序的健壮性和稳定性。

  6. 用户体验: 为了更好的用户体验,可以考虑增加输入格式检测的功能,提供更友好的错误提示和辅助信息,让用户更容易理解并纠正输入。

  7. 界面布局与交互: 按钮和文本框的布局和样式对用户体验至关重要。优化布局和添加适当的反馈可以提升用户使用体验。


好了~ 本文就到这里了,感谢您的阅读,每天还有更多的实例学习文章等着你 🎆。别忘了点赞、收藏~ Thanks♪(・ω・)ノ 🍇。

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

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

相关文章

【MATLAB源码-第91期】基于matlab的4QAM和4FSK在瑞利(rayleigh)信道下误码率对比仿真。

操作环境&#xff1a; MATLAB 2022a 1、算法描述 正交幅度调制&#xff08;QAM&#xff0c;Quadrature Amplitude Modulation&#xff09;是一种在两个正交载波上进行幅度调制的调制方式。这两个载波通常是相位差为90度&#xff08;π/2&#xff09;的正弦波&#xff0c;因此…

解决在SwingBench压测时出现一些问题

解决在SwingBench压测时出现一些问题 压测时断层 1.问题来由&#xff1a;在进行swingbench压测的时候会出现断断续续的情况 2.导致原因&#xff1a; 我们通过查看日志文件&#xff0c;看看是什么情况 tail -100 /u01/app/oracle/diag/rdbms/orcl/orcl/trace/alert_orcl.l…

锂电行业废水及母液除铊解决方案,除铊树脂技术

锂电池原材料和生产设备的制造、电池回收和处理等&#xff0c;产业的发展会带来铊排放问题。除了锂电池生产过 程中存在的铊污染外&#xff0c;企业的生活污水或者初期雨水也含有铊&#xff0c;因为铊是一种广泛存在于自然环境中的 元素&#xff0c;存在于饮用水、土壤和食物中…

【三维重建】摄像机标定(张正友相机标定法)

摄像机标定的目的是为了求解摄像机的内、外参数 求解投影矩阵M 通过建立特殊的场景&#xff0c;我们能过得到多对世界坐标和对应图像坐标 根据摄像机几何可知 &#xff1a; &#xff0c;M是一个3*4的矩阵&#xff0c;令 通过一对点可以得到两个方程组&#xff0c;M中一共有11个…

Linux安全之auditd审计工具使用说明

一、auditd工具简介 audited是Linux审核系统的用户空间组件。它负责将审核记录写入磁盘。查看日志是通过ausearch或aureport实用程序完成的。审核系统或加载规则的配置是使用auditctl实用程序完成的。在启动过程中&#xff0c;/etc/audit/audit.rules中的规则由auditctl读取并加…

全新爱蜗影视优码双端影视源码v9.1/影视视频APP源码+支持代理/在线支付+支持对应苹果CMS

源码简介&#xff1a; 这个是最新爱蜗影视优码双端影视源码&#xff0c;作为实用方便的影视视频APP源码&#xff0c;它不仅支持代理/在线支付&#xff0c;而且也支持对应苹果CMS。 爱蜗影视优码双端影视支持对应苹果CMS支持代理在线支付 带图文教程&#xff0c;全新美化多功能…

深入理解OS--数值编码

信息的表示和处理 寻址和字节顺序 位于0x100处&#xff0c;int类型值0x01234567在大端和小端下的存储。 字符串的存储不受字节序影响。 移位 1.对左移&#xff0c;右边统一补0 2.对右移&#xff0c;分为算术右移&#xff0c;逻辑右移 算术右移下&#xff0c;左边补原最高有效…

jsoup登录日志平台后调企业微信机器人自动发送错误日志告警

一、需求&#xff1a;错误日志Top10告警发送 二、需求分解 jsoup实现登录&#xff0c;获取到cookie和token等用户鉴权信息获取接口相应的key值调用日志平台错误日志Top榜接口&#xff0c;查询到结果集调用企业微信机器人发送消息接口加上定时任务&#xff0c;可以实现定时发送…

【Unity3D】MAX聚合广告SDK——Pangle广告接入失败总结

Pangle, App Monetization Simplified 注册 登录 创建应用 创建广告单元 将其应用ID和广告ID关联到MAX广告。 下载Pangle Unity Plugin包&#xff0c;新建一个空工程&#xff08;很重要&#xff09; Unity版本2019.4.0f1 gradle plugin 4.2.0 gradle版本6.7.1 build_tools 34.…

SpringBoot : ch08 自动配置原理

前言 在现代的Java开发中&#xff0c;Spring Boot已经成为了一个备受欢迎的框架。它以其简化开发流程、提高效率和强大的功能而闻名&#xff0c;使得开发人员能够更加专注于业务逻辑的实现而不必过多地关注配置问题。 然而&#xff0c;你是否曾经好奇过Spring Boot是如何做到…

7000字+24张图带你彻底弄懂线程池

大家好&#xff0c;我是三友。今天跟大家聊一聊无论是在工作中常用还是在面试中常问的线程池&#xff0c;通过画图的方式来彻底弄懂线程池的工作原理&#xff0c;以及在实际项目中该如何自定义适合业务的线程池。 一、什么是线程池 线程池其实是一种池化的技术的实现&#xff0…

控制台gbk乱码

引用IntelliJ IDEA中 统一设置编码为utf-8或GBK-CSDN博客 特别注意file coding 的文件path和java的编码格式 配置

9.增删改操作

目录 一、插入操作 1、为表的所有字段插入数据 2、为表的指定字段插入数据 3、同时插入多条记录 4、将查询结果插入表中&#xff1a; 二、更新操作 三、删除操作 四、练习题 一、插入操作 在使用数据库之前&#xff0c;数据库中必须要有数据&#xff0c;MYSQL中使INSE…

ESP32-Web-Server编程-HTML 基础

ESP32-Web-Server编程-HTML 基础 概述 HTML(HyperText Markup Language) 是用来描述网页的一种语言。其相关内容存储在前端代码的 .html 文件中。 当浏览器向 web 服务器请求网页时&#xff0c;一个 HTML 文件被发送给浏览器&#xff0c;浏览器解释该文件的内容&#xff0c;…

【重磅】:Spring Initializer 已经不支持Java8,也就是SpringBoot2.x项目初始化

Spring Initializer 已经不支持Java8 问题描述解决方案升级java版本更换IDEA内置的Spring Initializer中 Server URL的镜像地址 问题描述 我们可以看到在IDEA内置的Spring Initializer中 Java版本选择模块已经不支持1.8了&#xff0c;同样的&#xff0c;官网也不再支持了 解决…

YOLOv8 onnx 文件推理多线程加速视频流

运行环境&#xff1a; MacOS&#xff1a;14.0Python 3.9Pytorch2.1onnx 运行时 模型文件&#xff1a; https://wwxd.lanzouu.com/iBqiA1g49pbc 密码:f40v 下载 best.apk后将后缀名修改为 onnx 即可模型在英伟达 T4GPU 使用 coco128 训练了 200 轮如遇下载不了可私信获取 代码…

Ubuntu18.04安装Ipopt-3.12.8流程

本文主要介绍在Ubuntu18.04中安装Ipopt库的流程&#xff0c;及过程报错的解决方法&#xff0c;已经有很多关于Ipopt安装的博客&#xff0c;但经过我的测试&#xff0c;很多都失效了&#xff0c;经过探索&#xff0c;找到可流畅的安装Ipopt的方法&#xff0c;总结成本篇博客。 …

《尚品甄选》:后台系统——权限管理之菜单管理,递归实现树形结构查询(debug一遍)

文章目录 一、表结构设计二、菜单管理接口2.1 查询菜单2.2 添加菜单2.3 修改菜单2.4 删除菜单 三、分配菜单3.1 查询菜单3.2 保存菜单(批量插入) 四、动态菜单五、解决bug 一、表结构设计 菜单管理就是对系统的首页中的左侧菜单进行维护。 一个用户可以担任多个角色&#xff…

解密人工智能:线性回归

导言 人工智能&#xff08;AI&#xff09;已经成为当今科技领域的热门话题&#xff0c;其应用领域涵盖了各个行业。线性回归作为人工智能中的一种关键统计学方法&#xff0c;被广泛应用于预测和决策支持系统中。本文将为您详细介绍线性回归在人工智能中的应用原理与方法&#x…