You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

求助:基于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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.13 07:06:09