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

Tkinter Treeview绑定<ButtonPress-1>时selection()获取选中项异常

问题原因

绑定<ButtonPress-1>时,你的状态检查函数会在Treeview内部完成选中状态更新之前被触发。Tkinter中Treeview的选中逻辑属于按钮按下事件的后续处理环节,所以此时调用tree.selection()只能拿到上一次的选中结果,就出现了你遇到的延迟错位问题。

方案1:使用Treeview专属选中事件(推荐)

Treeview自带<<TreeviewSelect>>事件,这个事件会在选中状态真正更新完成后触发,不仅响应即时,还能正确获取最新选中项,同时兼容键盘操作(比如用上下箭头切换选中行),是处理这类需求的标准方式。

只需要把原来的事件绑定代码替换成:

tree.bind('<<TreeviewSelect>>', disablebutton_statecheck)

方案2:强制延迟执行状态检查(仅当必须用时)

如果因为特殊需求必须绑定<ButtonPress-1>,可以通过after_idle()让状态检查逻辑在Tkinter处理完当前所有待处理事件(包括Treeview的选中更新)后再执行:

修改状态检查函数和事件绑定:

def disablebutton_statecheck(event=None):                      
    # 让Tk先处理完所有待处理事件,再执行选中状态检查
    window.after_idle(_check_selection)

def _check_selection():
    print("triggered statecheck")
    selected_items = list(tree.selection())
    print(selected_items)
    print(len(selected_items))
    if len(selected_items) > 0:
        button_6.state(["!disabled"])
    else:
        button_6.state(["disabled"])

# 绑定<ButtonPress-1>事件
tree.bind('<ButtonPress-1>', disablebutton_statecheck)

这样就能保证调用tree.selection()时,Treeview已经完成了选中状态的更新。

完整修复代码(方案1版本)
import tkinter as tk
from tkinter import *
from tkinter import ttk

alternate = 1

def add_row():
    global alternate
    if alternate == 0:
        tree.insert('', tk.END,text="L1",values=("Big1","Test12345"))
        alternate = 1
    elif alternate == 1:
        tree.insert('', tk.END,text="L1",values=("Big1","Test"))
        alternate = 0

def delete_row():
    last = tree.get_children()[-1]
    tree.delete(last)
    disablebutton_statecheck()

def disablebutton_statecheck(event=None):                      
    print("triggered statecheck")
    print(list(tree.selection()))
    print(len(tree.selection()))
    if len(tree.selection()) > 0:
        button_6.state(["!disabled"])
    else:
        button_6.state(["disabled"])
    
        
window = Tk()
window.title("test window")
window.geometry("600x600+0+0")
section_1 = Frame(window, width = 600, height = 600, bg="#faf")
section_1.place(x=0, y=0)

tabControl_1 = ttk.Notebook(section_1, height = 470, width = 395) #395
tab1 = ttk.Frame(tabControl_1)

tabControl_1.add(tab1, text='Devices')
tabControl_1.place(y=10,x=25)

tree = ttk.Treeview(tab1, height=7)
tree.place(x=30, y=95)
tree.bind('<Motion>', 'break')

tree["columns"] = ("one", "two")
tree['show'] = 'headings'
tree.column("one", width=100, anchor='c', stretch=False)
tree.column("two", width=100, anchor='c', stretch=False)
tree.heading("one", text="Account")
tree.heading("two", text="Type")
tree.insert("",'end', text="L1",values=("Test","Test12345"))

button_1 = ttk.Button(tab1, text="add a row", command=add_row, width=17)
button_1.place(x=50, y=360)

button_2 = ttk.Button(tab1, text="delete row", command=delete_row, width=17)
button_2.place(x=200, y=360)

button_6 = ttk.Button(tab1, text="disable", width=17)               
button_6.place(x=50, y= 50)                                         

# 替换为Treeview专属选中事件
tree.bind('<<TreeviewSelect>>', disablebutton_statecheck)              
disablebutton_statecheck()                                          

window.resizable(False,False)
window.mainloop()

内容的提问来源于stack exchange,提问作者Jones659

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 03:50:41