求助:基于MySQL数据实现Tkinter层级TreeView的递归加载函数
解决MySQL层级数据加载到Tkinter TreeView的递归问题
问题说明
需要基于包含ID、ID_parent、Description列的MySQL表构建层级TreeView,已完成第一级列表填充,但无法编写递归函数加载子节点及其后代节点。
修正后的完整代码
import tkinter as tk from tkinter import * from tkinter import ttk import mysql.connector from tkinter.font import nametofont # 补充导入PIL模块处理图标 from PIL import Image, ImageTk def add_child(parent_id, tree, cursor, icon): """递归填充子节点及其后代""" # 查询当前父节点下的所有子节点 cursor.execute(""" SELECT ID, ID_PARENT, DESCRIPTION FROM employees WHERE ID_PARENT = %s ORDER BY ID """, (parent_id,)) rows = cursor.fetchall() for record in rows: node_id = record[0] # 用数据库ID作为TreeView节点的iid,方便后续关联操作 tree.insert( parent=parent_id, index='end', iid=node_id, text=f"{record[0]} - {record[2]}", image=icon, values=(record[0], record[2]) ) # 递归调用,加载当前子节点的后代 add_child(node_id, tree, cursor, icon) root = tk.Tk() root.resizable(False,False) root.configure(bg="#595252") root.title("Treeview") style=ttk.Style() style.theme_use('default') style.configure("Treeview", background="#D3D3D3", foreground="black", rowheight=34, fieldbackground="#D3D3D3",font=['Calibri',12,'normal']) tree_frame=Frame(root) tree_frame.pack(padx=10,pady=5) tree_scroll=Scrollbar(tree_frame) tree_scroll.pack(side=RIGHT,fill=Y) my_tree=ttk.Treeview(tree_frame,yscrollcommand=tree_scroll.set,selectmode='extended', height=12) my_tree.pack(fill="both",expand=True) tree_scroll.config(command=my_tree.yview) my_tree.column("#0", width=500, stretch=NO ) my_tree.heading("#0",text="ID", anchor=W) style.map('Treeview', background=[('selected','#347083')]) nametofont("TkHeadingFont").configure(size=12) # 加载图标,添加异常捕获避免路径错误导致崩溃 try: icon = ImageTk.PhotoImage(Image.open("I:/Progetti/Image/VerdeS2.ico")) except Exception as e: print(f"图标加载失败: {e}") icon = None # 创建根节点H1 my_tree.insert("", "end", "H1", text="H1") # 连接数据库并加载层级数据 conn = mysql.connector.connect(user='root', password='', host='localhost', database='employees') c = conn.cursor() # 加载第一级节点并递归加载所有后代 add_child("H1", my_tree, c, icon) conn.close() # 以下按钮的功能需自行实现,可取消注释并补充函数逻辑 # def add_child_item(): # # 实现添加子节点的逻辑 # pass # def add_sibling_item(): # # 实现添加兄弟节点的逻辑 # pass # def delete_item(): # # 实现删除节点的逻辑 # pass # add_child_button = tk.Button(root, text="Add Child Item", command=add_child_item) # add_child_button.pack() # add_sibling_button = tk.Button(root, text="Add Sibling Item", command=add_sibling_item) # add_sibling_button.pack() # delete_button = tk.Button(root, text="Delete Item", command=delete_item) # delete_button.pack() root.mainloop()
关键修正点说明
- 递归函数逻辑:
add_child函数接收父节点ID、TreeView对象、数据库游标和图标作为参数,避免全局变量依赖- 查询当前父节点下的所有子节点,遍历插入TreeView后,递归调用自身加载子节点的后代
- 节点关联优化:用数据库中的
ID作为TreeView节点的iid,方便后续添加、删除节点时关联数据库数据 - 模块补充与错误处理:添加
PIL模块导入确保图标加载,增加异常捕获避免路径错误导致程序崩溃 - 数据库查询优化:移除不必要的
GROUP BY,避免数据丢失,仅保留排序逻辑保证层级顺序
内容的提问来源于stack exchange,提问作者stefano visco
相关产品推荐
相关产品推荐

