为什么在清除 Treeview 选择后,我的按钮在第一次按下时不会隐藏,但在第二次按下后会隐藏

Why, after clearing a Treeview selection, will my Button not hide when pressed the first time but will after being pressed a second time

在下面的代码中,我有一个 Treeview 和一个按钮。 Whenever an item in the Treeview is selected, I want the button to appear, when ever the button is pressed, I want to deselect the selected Treeview item, and then have the button disappear.

这几乎行得通。正在发生的事情是,只要按下按钮,树视图选择就会被取消选择,但它不会消失。如果再次按下该按钮(在树视图中未选择任何内容),它将消失。

当我调试它时,我可以看到 table_row_selected 函数会在 clear_selection 函数 运行 时被调用。我认为这与 table.selection_remove 激活 table

上的绑定有关

有什么想法可以让这个功能发挥作用吗?

import tkinter as tk
from tkinter import ttk


# Whenever a table row is selected, show the 'clear_button'
def table_row_selected(clear_button):
    clear_button.grid(column=0, row=1)


# Whenver clear_button is clicked, clear the selections from the
# table, then hide the button
def clear_selection(table, clear_button):
    for i in table.selection():
        table.selection_remove(i)
    clear_button.grid_forget()

root = tk.Tk() 

content = ttk.Frame(root)
table = ttk.Treeview(content)

# Create clear_button, call configure to assign command that hides clear_button
clear_button = ttk.Button(content, text='Clear')
clear_button.configure(command=lambda: clear_selection(table, clear_button))

# Setup table columns
table['columns'] = 'NAME'
table.heading('NAME', text='Name')

# Layout widgets
content.grid(column=0, row=0)
table.grid(column=0, row=0)

# Bind selection to tree widget, call table_row_selected
table.bind('<<TreeviewSelect>>', lambda event: table_row_selected(clear_button))

# Fill in dummy data
for i in ['one', 'two', 'three']:
    table.insert('', tk.END, values=i)

root.mainloop()

基于 <<TreeviewSelect>> 上的 document

<<TreeviewSelect>>
    Generated whenever the selection changes.

因此,只要选择发生变化,就会执行回调,无论是选择还是取消选择。因此,当您清除所有选择时,将执行回调并显示按钮。

需要检查table_row_selected()里面是否有选中的item来判断是否显示按钮:

def table_row_selected(clear_button):
    if table.selection():
        clear_button.grid(column=0, row=1)

如果要将树视图作为参数传递,则需要更改函数的定义以及函数的调用方式:

def table_row_selected(table, clear_button):
    if table.selection():
        clear_button.grid(column=0, row=1)

...

table.bind('<<TreeviewSelect>>', lambda event: table_row_selected(event.widget, clear_button))

...

请注意,您可以使用

table.selection_set('')

替换:

for i in table.selection():
    table.selection_remove(i)