使用PySimpleGUI的sg.Tree()构建PDF阅读器树形目录及替代方案问询
解决PySimpleGUI中PDF目录树形显示的问题
一、用TreeData实现层级目录的方法
刚好我之前做过类似的PDF阅读器目录功能,你的目录列表格式是[层级, 标题, 页码],这种线性的层级列表可以通过维护一个父节点栈来轻松转换为TreeData结构,具体思路如下:
- 初始化一个空栈,用来记录每个层级对应的父节点ID
- 遍历每一条目录项:
- 根据当前层级,从栈中取出对应的父节点(比如层级2的父节点是栈中最近的层级1节点)
- 向TreeData中添加当前节点,同时把页码存在节点的values里,方便后续实现跳转功能
- 更新栈:如果当前层级比栈的长度大,就把当前节点ID压入栈;如果相等,就替换栈对应位置的元素;如果更小,就截断栈到对应长度再替换
下面是可以直接运行的完整代码示例:
import PySimpleGUI as sg # 你的PDF目录数据 pdf_toc = [ [1, 'Cover', 1], [1, 'PART ONE OVERVIEW', 25], [2, 'Chapter 1 Introduction', 27], [3, '1.1 What Operating Systems Do', 28], [3, '1.2 Computer-System Organization', 31], [3, '1.3 Computer-System Architecture', 36], [2, 'Chapter 2 Operating-System Structures', 79], [3, '2.1 Operating-System Services', 79], [3, '2.2 User and Operating-System Interface', 82], [3, '2.3 System Calls', 86], [1, 'PART TWO PROCESS MANAGEMENT', 127], [2, 'Chapter 3 Processes', 129], [3, '3.1 Process Concept', 129] ] def build_tree_data(toc_data): tree_data = sg.TreeData() parent_stack = [] # 存储各层级的父节点ID,索引对应层级-1 for level, title, page in toc_data: # 确定父节点:层级1的父是根(空字符串),其他层级取栈中对应位置的节点 if level == 1: parent_id = '' else: parent_id = parent_stack[level-2] # 创建唯一的节点ID,避免重复 node_id = f"{title}_{page}" # 添加节点到TreeData,values字段存页码 tree_data.Insert(parent_id, node_id, title, [page]) # 更新父节点栈,保证栈的长度始终对应当前层级的深度 if level > len(parent_stack): parent_stack.append(node_id) else: parent_stack = parent_stack[:level-1] parent_stack[-1] = node_id return tree_data # 构建窗口布局 layout = [ [sg.Tree( data=build_tree_data(pdf_toc), headings=['页码'], auto_size_columns=True, num_rows=20, col0_width=40, key='-TREE-', show_expanded=False )], [sg.Text('当前选中页码:'), sg.Text('', key='-PAGE-')] ] window = sg.Window('PDF阅读器目录', layout) while True: event, values = window.read() if event == sg.WIN_CLOSED: break # 处理树形节点点击事件,显示对应页码 if event == '-TREE-': selected_item = values['-TREE-'] if selected_item: node = window['-TREE-'].TreeData.nodes[selected_item] window['-PAGE-'].update(node.values[0]) window.close()
二、有没有TreeData的替代方案?
目前PySimpleGUI的sg.Tree()组件主要依赖TreeData作为数据源,官方并没有提供其他内置的数据结构来替代。不过你可以有两种变通方式:
- 自定义转换函数:把其他格式的目录数据(比如嵌套字典、递归结构)转换成TreeData,就像上面的
build_tree_data函数一样,适配自己的数据源格式 - 手动嵌套组件:如果需求特殊,也可以用多个
sg.Frame或者sg.Column手动嵌套实现树形结构,但这种方式会非常繁琐,维护成本高,远不如用TreeData高效
所以最推荐的还是用TreeData配合栈遍历的方法来处理你的目录列表,代码简洁且完全符合PySimpleGUI的设计逻辑。
内容的提问来源于stack exchange,提问作者Zain Arshad
相关产品推荐
相关产品推荐

