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

咨询:Tkinter表格添加顶点最小距离数据报错的解决方法

问题:Tkinter Treeview更新distance列时出现“Item 1 is not found”错误

需求为基于Tkinter表格构建图,用户输入顶点名称、X/Y坐标,distance列初始为空;添加数据后计算每个顶点的最小距离并填入该列。现有代码尝试用table.set更新列时,触发“Item 1 is not found”错误。


错误原因

  1. Treeview项ID误用:你用f"{i+1}"作为项ID,但Treeview的子项ID是插入时自动生成的唯一标识(如I001),并非你在text参数中设置的序号。
  2. 重复创建窗口:代码中两次执行window = Tk(),导致第一个窗口的控件与第二个窗口的表格无关联,无法正确获取子项。
  3. 数据插入格式错误:add_data函数的values参数多传了一个元素,导致列对应关系混乱。
  4. 距离计算逻辑偏差:原代码仅计算两两顶点的距离,未实现“找出每个顶点最小距离”的需求,反而尝试直接填入两两距离。

修复方案

  1. 记录Treeview项ID:插入数据时保存自动生成的项ID,或在获取表格数据时同步记录,确保更新时能定位到正确项。
  2. 统一窗口实例:仅创建一个主窗口,避免控件归属混乱。
  3. 修正数据插入格式:保证values参数的元素数量与列数匹配。
  4. 实现最小距离计算:对每个顶点,遍历所有关联距离并筛选最小值,再更新表格。

修复后的完整代码

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.05 03:12:32