使用Python和PyQt5打造一个JSON快速查看器

Written by

in

文章目录
  • 需求非常简单: 支持从文件拖拽或文件选择框加载 JSON 文件 输入 KEY,快速显示对应的值 KEY 支持「点语法」和列表下标: name user.name items.0.id 界面要尽量简洁,美观,适合日常调试 JSON 时快速使用 最终效果: 顶部标题 + 提示语,说明工具用途和操作方式 中间一行显示当前 JSON 文件路径 + 打开按钮 一行 KEY 输入 + 查询按钮 下方大区域显示查询结果(支持格式化 JSON) 底部状态栏显示操作结果提示(成功 / 失败)
  • 本工具的主体代码全部在一个文件中: 主文件:main.py 主类:JsonViewer(QMainWindow) 入口函数:main() 入口函数代码: def main(): app = QApplication(sys.argv) viewer = JsonViewer() viewer.show() sys.exit(app.exec_()) if __name__ == “__main__”: main() 这是典型的 PyQt5 应用启动方式: 创建 QApplication 实例 实例化主窗口 JsonViewer 显示窗口 进入事件循环
  • 整个 main.py 代码量不大,却完成了: 一个小而美的 PyQt5 窗口应用 支持拖拽 / 打开 JSON 文件 支持 KEY 路径解析(对象 + 列表) 自适应格式化输出结果 简单但实用的状态提示和 UI 美化 如果需要扩展,这个工具还可以进一步完善: 支持 a[0].b 这种带中括号的路径语法 增加「历史 KEY」下拉列表,快速重复查询 添加「复制结果」按钮,一键复制查询结果 增加「JSON 树形视图」,可视化浏览整个结构
  • 这篇文章从需求出发,完整拆解了 main.py 中的实现: 如何用 PyQt5 快速搭建一个桌面小工具 如何用样式表和字体调整让界面更友好 如何通过拖拽和文件选择加载 JSON 如何用简单的「点语法 + 数字下标」解析 JSON 路径 如果你也经常需要调试接口或查看复杂 JSON,不妨参考这个实现,按自己的习惯继续扩展,让它成为你日常开发中的一个趁手小工具。 以上就是Python使用PyQt5打造一个JSON快速查看器的详细内容,更多关于PyQt5 JSON快速查看器的资料请关注风君子博客其它相关文章! 您可能感兴趣的文章: 使用Python和PyQt5开发一个多功能音乐播放器 基于Python+PyQt5+Pandas编写的带图形界面的Excel合并工具 Python+PyQt5开发一个Windows EXE程序在线更新工具 PyQt5实现多界面自由切换的完整项目实践指南 Python基于PyQt5和openpyxl实现Excel单元格合并工具
  • 目录
    • 一、需求与效果
    • 二、项目结构与入口
    • 三、窗口与整体样式设计
      • 1. 主窗口类与基础设置
      • 2. 设置窗口大小与全局样式
    • 四、布局与控件拆解
      • 1. 主布局与标题区
      • 2. 文件选择行(显示路径 + 打开按钮)
      • 3. KEY 输入行(KEY + 输入框 + 查询按钮)
      • 4. 结果显示区与状态栏
    • 五、拖拽与打开 JSON 文件
      • 1. 开启拖拽支持
      • 2. 通过文件选择框打开 JSON
      • 3. 加载 JSON 文件
    • 六、KEY 路径解析与查询逻辑
      • 1. 查询入口函数
      • 2. 路径解析核心函数
    • 七、少量代码实现一个高频小工具
      • 八、小结

        最近写了一个小工具:只要拖入或打开一个 JSON 文件,输入 KEY,就能快速查看对应的值。本文以 d:测试Github项目59-JOSN快速查看器main.py 为例,完整拆解这个 PyQt5 小工具的实现思路和关键代码。

        需求非常简单:

        • 支持从文件拖拽或文件选择框加载 JSON 文件
        • 输入 KEY,快速显示对应的值
        • KEY 支持「点语法」和列表下标:
          • name
          • user.name
          • items.0.id
        • 界面要尽量简洁,美观,适合日常调试 JSON 时快速使用

        最终效果:

        • 顶部标题 + 提示语,说明工具用途和操作方式
        • 中间一行显示当前 JSON 文件路径 + 打开按钮
        • 一行 KEY 输入 + 查询按钮
        • 下方大区域显示查询结果(支持格式化 JSON)
        • 底部状态栏显示操作结果提示(成功 / 失败)

        本工具的主体代码全部在一个文件中:

        • 主文件:main.py
        • 主类:JsonViewer(QMainWindow)
        • 入口函数:main()

        入口函数代码:

        def main():
            app = QApplication(sys.argv)
            viewer = JsonViewer()
            viewer.show()
            sys.exit(app.exec_())
        
        
        if __name__ == "__main__":
            main()
        

        这是典型的 PyQt5 应用启动方式:

        1. 创建 QApplication 实例
        2. 实例化主窗口 JsonViewer
        3. 显示窗口
        4. 进入事件循环

        主窗口继承自 QMainWindow

        class JsonViewer(QMainWindow):
            def __init__(self):
                super().__init__()
                self.data = None
                self.current_path = None
                self.init_ui()
        
        • self.data:用来保存当前加载的 JSON 对象
        • self.current_path:记录当前 JSON 文件路径
        • init_ui():负责创建和布局所有控件,并设置样式

        def init_ui(self):
            self.setWindowTitle("JSON快速查看器")
            self.resize(800, 520)
        
            self.setStyleSheet(
                """
                QWidget {
                    background-color: #f5f5f7;
                    font-family: "Microsoft YaHei";
                    font-size: 10pt;
                }
                QPushButton {
                    background-color: #0078d7;
                    color: white;
                    border-radius: 4px;
                    padding: 6px 14px;
                }
                QPushButton:hover {
                    background-color: #0a84ff;
                }
                QPushButton:pressed {
                    background-color: #005a9e;
                }
                QLineEdit, QTextEdit {
                    background-color: #ffffff;
                    border: 1px solid #d0d0d5;
                    border-radius: 4px;
                }
                QLineEdit:focus, QTextEdit:focus {
                    border: 1px solid #0a84ff;
                }
                """
            )
        

        这里用了一段简单的 Qt 样式表(类似 CSS):

        • 全局字体:微软雅黑 10pt
        • 背景色:淡灰色 #f5f5f7
        • 按钮:蓝色背景 + 白字 + 圆角 + 悬停 / 按下态
        • 输入框和文本框:白色背景 + 边框 + 聚焦时高亮

        通过一次性设置 QWidget 和各控件的样式,可以避免对每个控件逐个设置属性,代码更简洁,视觉也更统一。

        central_widget = QWidget()
        self.setCentralWidget(central_widget)
        
        main_layout = QVBoxLayout()
        central_widget.setLayout(main_layout)
        main_layout.setContentsMargins(20, 18, 20, 18)
        main_layout.setSpacing(12)
        
        self.info_label = QLabel("JSON 快速查看器")
        self.info_label.setAlignment(Qt.AlignCenter)
        title_font = self.info_label.font()
        title_font.setPointSize(14)
        title_font.setBold(True)
        self.info_label.setFont(title_font)
        main_layout.addWidget(self.info_label)
        
        subtitle = QLabel("拖入 JSON 文件到窗口,或点击右侧按钮选择文件")
        subtitle.setAlignment(Qt.AlignCenter)
        subtitle.setStyleSheet("color: #666666;")
        main_layout.addWidget(subtitle)
        
        • 纵向布局 QVBoxLayout:从上到下堆叠各个区域
        • 主标题用 14 号加粗字体,居中显示
        • 副标题用浅灰色,提示使用方法

        file_layout = QHBoxLayout()
        self.file_label = QLabel("未选择文件")
        self.file_label.setMinimumWidth(300)
        self.file_label.setTextInteractionFlags(Qt.TextSelectableByMouse)
        self.file_label.setStyleSheet("color: #555555;")
        open_button = QPushButton("打开JSON")
        open_button.clicked.connect(self.open_file)
        file_layout.addWidget(self.file_label)
        file_layout.addWidget(open_button)
        main_layout.addLayout(file_layout)
        

        设计要点:

        • 使用水平布局 QHBoxLayout,左边是文件路径,右边是按钮
        • 文件路径标签支持鼠标选中,方便复制路径
        • 初始提示为「未选择文件」

        key_layout = QHBoxLayout()
        key_label = QLabel("KEY:")
        key_label.setStyleSheet("color: #333333;")
        self.key_edit = QLineEdit()
        self.key_edit.setPlaceholderText("例如: user.name 或 items.0.id")
        key_font = self.key_edit.font()
        key_font.setPointSize(10)
        self.key_edit.setFont(key_font)
        search_button = QPushButton("查询")
        search_button.clicked.connect(self.lookup_key)
        self.key_edit.returnPressed.connect(self.lookup_key)
        key_layout.addWidget(key_label)
        key_layout.addWidget(self.key_edit)
        key_layout.addWidget(search_button)
        main_layout.addLayout(key_layout)
        

        细节设计:

        • 提示语直接告诉用户 KEY 的写法示例
        • 支持两种触发方式:
          • 点击「查询」按钮
          • 在输入框里按 Enter(returnPressed 信号)

        self.result_edit = QTextEdit()
        self.result_edit.setReadOnly(True)
        result_font = self.result_edit.font()
        result_font.setFamily("Consolas")
        result_font.setPointSize(10)
        self.result_edit.setFont(result_font)
        main_layout.addWidget(self.result_edit)
        
        self.status_label = QLabel("")
        self.status_label.setStyleSheet("color: #2e7d32;")
        main_layout.addWidget(self.status_label)
        
        • 结果用 QTextEdit 展示,适合显示多行 JSON
        • 使用等宽字体 Consolas,方便对齐与阅读
        • 底部 status_label 用来显示提示信息:
          • JSON 加载成功
          • 未找到对应的值
          • 请先加载 JSON 文件
            等等

        self.setAcceptDrops(True)
        

        然后重写两个事件函数:

        def dragEnterEvent(self, event):
            if event.mimeData().hasUrls():
                for url in event.mimeData().urls():
                    path = url.toLocalFile()
                    if path.lower().endswith(".json"):
                        event.acceptProposedAction()
                        return
            event.ignore()
        

        逻辑:

        • 拖入的内容如果包含文件 URL
        • 且其中有 .json 后缀的文件
        • 则接受这次拖拽,否则忽略

        真正的放下事件:

        def dropEvent(self, event):
            for url in event.mimeData().urls():
                path = url.toLocalFile()
                if path.lower().endswith(".json"):
                    self.load_json(path)
                    break
        
        • 取第一个 .json 文件的路径
        • 调用 load_json 进行加载

        def open_file(self):
            path, _ = QFileDialog.getOpenFileName(
                self,
                "选择 JSON 文件",
                "",
                "JSON Files (*.json);;All Files (*)",
            )
            if path:
                self.load_json(path)
        

        使用 QFileDialog.getOpenFileName

        • 默认过滤器是 .json 文件
        • 也可以切换为「所有文件」打开

        def load_json(self, path):
            try:
                with open(path, "r", encoding="utf-8") as f:
                    self.data = json.load(f)
                self.current_path = path
                self.file_label.setText(path)
                self.status_label.setText("JSON 加载成功")
                self.result_edit.clear()
            except Exception as e:
                self.data = None
                self.current_path = None
                self.file_label.setText("未选择文件")
                self.status_label.setText("加载失败: {0}".format(e))
                self.result_edit.clear()
        
        • 成功:
          • json.load 解析为 Python 对象(dict / list)
          • 更新当前路径显示
          • 清空结果区域
          • 状态显示为「JSON 加载成功」
        • 失败:
          • 清空状态
          • 文件标签重置
          • 状态栏显示错误原因

        def lookup_key(self):
            if self.data is None:
                self.status_label.setText("请先加载 JSON 文件")
                return
        
            key_path = self.key_edit.text().strip()
            if not key_path:
                self.status_label.setText("请输入 KEY")
                return
        
            try:
                value = self.get_value_by_path(self.data, key_path)
            except (KeyError, IndexError, TypeError):
                self.status_label.setText("未找到对应的值")
                self.result_edit.clear()
                return
        
            if isinstance(value, (dict, list)):
                text = json.dumps(value, ensure_ascii=False, indent=2)
            else:
                text = str(value)
        
            self.result_edit.setPlainText(text)
            self.status_label.setText("查询成功")
        

        逻辑分几步:

        1. 检查是否已加载 JSON
        2. 检查 KEY 是否为空
        3. 调用 get_value_by_path 获取值,捕获各种失败情况
        4. 如果结果是 dictlist,用 json.dumps 美化输出
        5. 否则直接转成字符串显示

        def get_value_by_path(self, data, path):
            if not path:
                return data
        
            current = data
            parts = path.split(".")
        
            for part in parts:
                if isinstance(current, list) and part.isdigit():
                    index = int(part)
                    current = current[index]
                elif isinstance(current, dict):
                    if part in current:
                        current = current[part]
                    else:
                        raise KeyError(part)
                else:
                    raise KeyError(part)
        
            return current
        

        这个函数支持的语法:

        • 对象键:
          • user.name 会依次访问 data["user"]["name"]
        • 列表下标:
          • items.0 相当于 data["items"][0]
          • items.0.id 相当于 data["items"][0]["id"]

        实现方式:

        1. 把路径按 . 切分为列表 ["items", "0", "id"]
        2. 从根对象开始,逐层向下走
        3. 当前对象是 list 且当前 part 是数字时:
          • 解析成 int 下标,访问对应元素
        4. 当前对象是 dict 时:
          • 直接按照键访问
        5. 如果中途类型不匹配或键不存在,就抛异常,由调用方统一处理为「未找到对应的值」

        这个函数逻辑简单清晰,但已经覆盖了绝大部分日常 JSON 调试的需求。

        整个 main.py 代码量不大,却完成了:

        • 一个小而美的 PyQt5 窗口应用
        • 支持拖拽 / 打开 JSON 文件
        • 支持 KEY 路径解析(对象 + 列表)
        • 自适应格式化输出结果
        • 简单但实用的状态提示和 UI 美化

        如果需要扩展,这个工具还可以进一步完善:

        • 支持 a[0].b 这种带中括号的路径语法
        • 增加「历史 KEY」下拉列表,快速重复查询
        • 添加「复制结果」按钮,一键复制查询结果
        • 增加「JSON 树形视图」,可视化浏览整个结构

        这篇文章从需求出发,完整拆解了 main.py 中的实现:

        • 如何用 PyQt5 快速搭建一个桌面小工具
        • 如何用样式表和字体调整让界面更友好
        • 如何通过拖拽和文件选择加载 JSON
        • 如何用简单的「点语法 + 数字下标」解析 JSON 路径

        如果你也经常需要调试接口或查看复杂 JSON,不妨参考这个实现,按自己的习惯继续扩展,让它成为你日常开发中的一个趁手小工具。

        以上就是Python使用PyQt5打造一个JSON快速查看器的详细内容,更多关于PyQt5 JSON快速查看器的资料请关注风君子博客其它相关文章!

        您可能感兴趣的文章:

        • 使用Python和PyQt5开发一个多功能音乐播放器
        • 基于Python+PyQt5+Pandas编写的带图形界面的Excel合并工具
        • Python+PyQt5开发一个Windows EXE程序在线更新工具
        • PyQt5实现多界面自由切换的完整项目实践指南
        • Python基于PyQt5和openpyxl实现Excel单元格合并工具

        站内搜索