Tkinter TreeView插入父子关系报错:Item未找到问题求助
解决Tkinter TreeView父子层级插入的父索引错误
问题背景
尝试在Tkinter TreeView中插入指定的父子层级关系时,遇到_tkinter.TclError: Item A not found错误,无法正确构建树形结构。需要插入的父子关系如下:
| Child | Parent |
|---|---|
| A1 | A |
| A11 | A1 |
| A112 | A11 |
| A113 | A11 |
| A1121 | A112 |
| A11211 | A1121 |
| B1 | B |
| B11 | B1 |
| B12 | B1 |
| B111 | B11 |
用户原代码:
import pandas as pd from tkinter import * import tkinter as tk from tkinter import ttk root = tk.Tk() df2=pd.read_csv('c:/erp/book22.csv') df_list=list(df2.columns.values) df_rset=df2.to_numpy().tolist() df_tree5=ttk.Treeview(root,columns=df_list) df_tree5.pack() for i in df_list: df_tree5.column(i,width=100,anchor='c') df_tree5.heading(i,text=i) for dt in df_rset: v=[r for r in dt] df_tree5.insert(v[0],tk.END, text=v[1]) root.mainloop()
报错信息:
File "c:\mainfol\mfatt\TREEINTREEEVIW.PY", line 16, in <module> df_tree5.insert(v[0],tk.END, text=v[1]) File "C:\Users\Ali\AppData\Local\Programs\Python\Python312\Lib\tkinter\ttk.py", line 1339, in insert res = self.tk.call(self._w, "insert", parent, index, *opts) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ _tkinter.TclError: Item A not found df_tree5.insert(v[0],tk.END, text=v[1]) File "C:\Users\Ali\AppData\Local\Programs\Python\Python312\Lib\tkinter\ttk.py", line 1339, in insert res = self.tk.call(self._w, "insert", parent, index, *opts)
错误原因
- 参数顺序颠倒:
insert方法的第一个参数是父节点的ID,第二个是插入位置,text应该是当前节点的名称。原代码把Child作为父节点、Parent作为节点文本,完全搞反了逻辑。 - 父节点未提前创建:插入子节点时,对应的父节点(如A、B)还未被添加到TreeView中,导致Tcl无法找到父节点ID。
- 缺少顶级节点:A、B这类根节点没有被插入,它们的父节点应该是TreeView的根(用空字符串
''表示)。
修正方案
核心思路:
- 维护一个字典记录每个节点对应的TreeView item ID,确保子节点插入时父节点已存在。
- 先插入所有顶级节点(A、B),再按层级依次插入子节点;或者遍历数据时自动检查并创建缺失的父节点。
修正后的代码:
import pandas as pd import tkinter as tk from tkinter import ttk root = tk.Tk() # 读取数据 df2 = pd.read_csv('c:/erp/book22.csv') df_list = list(df2.columns.values) df_rset = df2.to_numpy().tolist() # 初始化TreeView df_tree5 = ttk.Treeview(root, columns=df_list) df_tree5.pack() # 设置列属性 for col in df_list: df_tree5.column(col, width=100, anchor='c') df_tree5.heading(col, text=col) # 维护节点ID映射:节点名称 -> TreeView item ID node_ids = {} # 第一步:收集所有需要的节点,先插入顶级节点(父节点不在Child列中的节点) all_children = [item[0] for item in df_rset] all_parents = [item[1] for item in df_rset] # 找出顶级节点(存在于父节点列表,但不在子节点列表中) top_nodes = set(all_parents) - set(all_children) # 插入顶级节点,父节点为根('') for node in top_nodes: # insert返回的是该节点的ID,存入字典 node_id = df_tree5.insert('', tk.END, text=node, values=[node, '']) node_ids[node] = node_id # 第二步:插入所有子节点,确保父节点已存在 for dt in df_rset: child_name = dt[0] parent_name = dt[1] # 检查父节点是否在映射中(确保已创建) if parent_name in node_ids: parent_id = node_ids[parent_name] # 插入子节点,values对应表格的Child和Parent列 child_id = df_tree5.insert(parent_id, tk.END, text=child_name, values=[child_name, parent_name]) node_ids[child_name] = child_id root.mainloop()
代码说明
- 节点ID映射字典:
node_ids记录每个节点名称对应的TreeView item ID,避免重复创建,同时确保子节点能找到正确的父节点ID。 - 顶级节点处理:通过集合运算找出所有顶级节点(A、B),先插入到TreeView的根节点下。
- 子节点插入:遍历数据时,先确认父节点已存在于映射中,再插入子节点,并将子节点的ID存入字典,供后续更深层级的节点使用。
内容的提问来源于stack exchange,提问作者Muhammad Fahim Aamir
相关产品推荐
相关产品推荐

