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

ttk.Treeview.focus()返回I001而非索引,如何正确更新树视图条目?

解决ttk.Treeview更新条目时的节点标识问题

问题说明

更新ttk.Treeview条目时,ttk.Treeview.focus()返回类似I001的节点标识字符串,而非预期的数字索引。之前通过截取标识最后一位作为索引的临时方案,在条目数量超过10条时会失效,属于不可靠的临时手段。

正确解决方法

方法1:直接更新节点值(推荐)

无需删除原节点再插入新节点,直接使用Treeview.item()方法修改选中节点的values属性,既保留原节点位置,又高效可靠。

修改后的update_record()函数:

def update_record():
    selected_items = register.selection()
    if not selected_items:
        return  # 无选中节点时直接返回
    new_value = (sn.get(), bn.get(), cn.get())
    for item in selected_items:
        register.item(item, values=new_value)  # 直接更新节点值
    # 清空输入框
    sn.delete(0, END)
    bn.delete(0, END)
    cn.delete(0, END)

方法2:删除原节点后在原位置插入(如需重建节点)

若必须删除原节点再插入新节点,不要依赖节点标识的字符串内容,改用Treeview.index()获取节点在父节点下的索引位置:

def update_record():
    selected_items = register.selection()
    if not selected_items:
        return
    new_value = (sn.get(), bn.get(), cn.get())
    for item in selected_items:
        parent = register.parent(item)  # 获取父节点(根节点为"")
        index = register.index(item)    # 获取节点在父节点下的索引
        register.delete(item)
        register.insert(parent, index, values=new_value)  # 在原位置插入
    # 清空输入框
    sn.delete(0, END)
    bn.delete(0, END)
    cn.delete(0, END)

完整修改代码

以下是替换方法1后的完整代码,同时优化了选中事件的处理逻辑:

from tkinter import *
from tkinter import ttk

root = Tk()

root.title("Treeview")
root.geometry("650x450")
root.resizable(True, True)

# 定义列
columns = ("Seller", "Buyer", "Contract Number")

# 创建Treeview
register = ttk.Treeview(root, columns=columns, show="headings")
register.grid(row=0, column=0, columnspan=3, padx=5, pady=5)

# 设置表头
register.heading(columns[0], text="Seller Name")
register.heading(columns[1], text="Buyer Name")
register.heading(columns[2], text="Contract Number")

# 设置列对齐
register.column(columns[0], anchor=CENTER)
register.column(columns[1], anchor=CENTER)
register.column(columns[2], anchor=CENTER)


# 添加条目
def add_entry():
    entry = (sn.get(), bn.get(), cn.get())
    register.insert("", END, values=entry)

    sn.delete(0, END)
    bn.delete(0, END)
    cn.delete(0, END)


ttk.Label(root, text="Add Entries below:", font=("Arial", 15)).grid(row=1, column=0, pady=5, padx=5, sticky=W)

ttk.Label(root, text="Seller Name:").grid(row=2, column=0, pady=5, padx=5, sticky=W)
ttk.Label(root, text="Buyer Name:").grid(row=3, column=0, pady=5, padx=5, sticky=W)
ttk.Label(root, text="Contract Number:").grid(row=4, column=0, pady=5, padx=5, sticky=W)

sn = ttk.Entry(root)
bn = ttk.Entry(root)
cn = ttk.Entry(root)

sn.grid(row=2, column=1, sticky=W)
bn.grid(row=3, column=1, sticky=W)
cn.grid(row=4, column=1, sticky=W)

add = ttk.Button(root, text="Add Entry", command=add_entry)
add.grid(row=5, column=0, columnspan=3, padx=5, pady=5, sticky=W)


# 更新模式变量
update = IntVar()


# 选中事件处理:删除或填充更新内容
def item_selected(event):
    selected_items = register.selection()
    if not selected_items:
        return
    if update.get() == 0:
        for selection in selected_items:
            register.delete(selection)
    else:
        # 清空输入框并填充选中条目的内容
        sn.delete(0, END), bn.delete(0, END), cn.delete(0, END)
        item_values = register.item(selected_items[0])["values"]
        sn.insert(0, item_values[0]), bn.insert(0, item_values[1]), cn.insert(0, item_values[2])


register.bind('<<TreeviewSelect>>', item_selected)


# 更新记录函数
def update_record():
    selected_items = register.selection()
    if not selected_items:
        return
    new_value = (sn.get(), bn.get(), cn.get())
    for item in selected_items:
        register.item(item, values=new_value)
    # 清空输入框
    sn.delete(0, END)
    bn.delete(0, END)
    cn.delete(0, END)


cb = ttk.Checkbutton(root, text="Update Records (on click)", variable=update)
cb.grid(row=6, column=0, padx=5, pady=5, sticky=W)

up = ttk.Button(root, text="Update Record", command=update_record)
up.grid(row=6, column=1, padx=15, pady=10, sticky=W)

root.mainloop()

关键知识点

  • Treeview.focus()返回的是Tkinter内部生成的节点唯一标识(item ID),格式不固定,绝对不能依赖其字符串内容提取索引。
  • Treeview.item(item_id, values=new_values)是更新节点内容的最优方式,无需修改节点位置或重建节点。
  • Treeview.index(item_id)可获取节点在父节点下的索引位置,该方法不受节点ID格式影响,是可靠的位置获取方式。

内容的提问来源于stack exchange,提问作者Code-Killer

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.13 21:40:27