咨询:Tkinter表格添加顶点最小距离数据报错的解决方法
问题:Tkinter Treeview更新distance列时出现“Item 1 is not found”错误
需求为基于Tkinter表格构建图,用户输入顶点名称、X/Y坐标,distance列初始为空;添加数据后计算每个顶点的最小距离并填入该列。现有代码尝试用table.set更新列时,触发“Item 1 is not found”错误。
错误原因
- Treeview项ID误用:你用
f"{i+1}"作为项ID,但Treeview的子项ID是插入时自动生成的唯一标识(如I001),并非你在text参数中设置的序号。 - 重复创建窗口:代码中两次执行
window = Tk(),导致第一个窗口的控件与第二个窗口的表格无关联,无法正确获取子项。 - 数据插入格式错误:
add_data函数的values参数多传了一个元素,导致列对应关系混乱。 - 距离计算逻辑偏差:原代码仅计算两两顶点的距离,未实现“找出每个顶点最小距离”的需求,反而尝试直接填入两两距离。
修复方案
- 记录Treeview项ID:插入数据时保存自动生成的项ID,或在获取表格数据时同步记录,确保更新时能定位到正确项。
- 统一窗口实例:仅创建一个主窗口,避免控件归属混乱。
- 修正数据插入格式:保证
values参数的元素数量与列数匹配。 - 实现最小距离计算:对每个顶点,遍历所有关联距离并筛选最小值,再更新表格。
修复后的完整代码
from tkinter import ttk, Tk, Label, Entry, Button import networkx as nx import matplotlib.pyplot as plt # 存储顶点名称与表格项ID的映射 table_item_ids = {} # 创建表格 def create_table(): global table table = ttk.Treeview(window) # 定义列 table["columns"] = ("name", "x_coord", "y_coord", "distance") table.column("#0", width=100, minwidth=100) table.column("name", width=100, minwidth=100) table.column("x_coord", width=100, minwidth=100) table.column("y_coord", width=100, minwidth=100) table.column("distance", width=100, minwidth=100) # 设置表头 table.heading("#0", text="序号") table.heading("name", text="顶点名称") table.heading("x_coord", text="X坐标") table.heading("y_coord", text="Y坐标") table.heading("distance", text="最小距离") table.pack() # 添加顶点数据到表格 def add_data(): name = entry_name.get().strip() x_coord = entry_x_coord.get().strip() y_coord = entry_y_coord.get().strip() if not (name and x_coord and y_coord): return # 空输入不处理 # 插入数据并获取自动生成的项ID item_id = table.insert("", "end", text=str(len(table.get_children()) + 1), values=(name, x_coord, y_coord, "")) # 记录顶点与项ID的映射 table_item_ids[name] = item_id # 清空输入框 entry_name.delete(0, "end") entry_x_coord.delete(0, "end") entry_y_coord.delete(0, "end") # 计算每个顶点的最小距离 def calculate_min_distances(vertices): min_distances = {} # 先计算所有两两顶点的距离 all_distances = {} for i in range(len(vertices)): for j in range(i + 1, len(vertices)): v1_name, v1_x, v1_y = vertices[i] v2_name, v2_x, v2_y = vertices[j] distance = ((v1_x - v2_x) ** 2 + (v1_y - v2_y) ** 2) ** 0.5 all_distances[(v1_name, v2_name)] = distance all_distances[(v2_name, v1_name)] = distance # 筛选每个顶点的最小距离 for v_name, _, _ in vertices: distances = [d for (v1, v2), d in all_distances.items() if v1 == v_name] if distances: min_dist = min(distances) min_distances[v_name] = round(min_dist, 2) else: min_distances[v_name] = "无" # 仅一个顶点时无距离 return min_distances # 构建图并更新表格 def build_graph(): # 从表格读取顶点数据 vertices = [] table_item_ids.clear() for child in table.get_children(): values = table.item(child)['values'] if len(values) >= 3: try: v_name = values[0] v_x = float(values[1]) v_y = float(values[2]) vertices.append((v_name, v_x, v_y)) table_item_ids[v_name] = child except ValueError: continue # 跳过格式错误的数据 if len(vertices) < 2: return # 至少两个顶点才能构建图 # 计算最小距离并更新表格 min_distances = calculate_min_distances(vertices) for v_name, dist in min_distances.items(): if v_name in table_item_ids: table.set(table_item_ids[v_name], "distance", str(dist)) # 构建网络图 G = nx.Graph() for vertex in vertices: G.add_node(vertex[0]) # 添加带权重的边 for i in range(len(vertices)): for j in range(i + 1, len(vertices)): v1_name, v1_x, v1_y = vertices[i] v2_name, v2_x, v2_y = vertices[j] distance = ((v1_x - v2_x) ** 2 + (v1_y - v2_y) ** 2) ** 0.5 G.add_edge(v1_name, v2_name, weight=round(distance, 2)) # 可视化图 pos = {v[0]: (v[1], v[2]) for v in vertices} nx.draw(G, pos, with_labels=True, node_size=700, node_color='lightblue', font_weight='bold', font_size=10, edge_color='grey', width=2) labels = nx.get_edge_attributes(G, 'weight') nx.draw_networkx_edge_labels(G, pos, edge_labels=labels) plt.show() # 主程序入口 window = Tk() window.geometry("500x500") window.title("顶点图构建工具") create_table() # 输入控件布局 label_name = Label(window, text="顶点名称:") label_name.pack(pady=2) entry_name = Entry(window) entry_name.pack(pady=2) label_x_coord = Label(window, text="X坐标:") label_x_coord.pack(pady=2) entry_x_coord = Entry(window) entry_x_coord.pack(pady=2) label_y_coord = Label(window, text="Y坐标:") label_y_coord.pack(pady=2) entry_y_coord = Entry(window) entry_y_coord.pack(pady=2) button_add = Button(window, text="添加顶点", command=add_data) button_add.pack(pady=5) build_graph_button = Button(window, text="构建图并计算最小距离", command=build_graph) build_graph_button.pack(pady=5) window.mainloop()
关键修复说明
- 项ID映射:通过
table_item_ids字典关联顶点名称与表格项ID,确保更新时能精准定位目标行。 - 窗口统一:仅创建一个主窗口,所有控件归属同一实例,避免关联错误。
- 逻辑修正:实现了“计算每个顶点最小距离”的核心需求,而非单纯记录两两距离。
- 输入校验:添加空输入和格式错误处理,提升程序稳定性。
内容的提问来源于stack exchange,提问作者dushnila
相关产品推荐
相关产品推荐

