简体   繁体   English

Tkinter - 使用单击而不是双击从 Treeview 中选择一个项目(回调 Treeview 项目选择)

[英]Tkinter - Selecting an item from a Treeview using single click instead of double click (Callback on Treeview item selection)

When you want to select an item in a Treeview, you usually use the double-click:当你想 select 一个 Treeview 中的一个项目时,你通常使用双击:

def print_element(event):
    print(my_treeview.selection()[0])
my_treeview.bind("<Double-1>", print_element)

Today I tried to do the same but using a single click instead:今天我尝试做同样的事情,但使用了一次单击:

my_treeview.bind("<Button-1>", print_element)

But it wouldn't work.但这行不通。 The output was just an empty tuple. output 只是一个空元组。 I started to search online for an explanation... why is it not working?我开始在网上搜索解释......为什么它不起作用?

EDIT: My goal was actually to do something every time a treeview item was selected.编辑:我的目标实际上是每次选择 treeview 项目时都do something

  • I proposed a solution myself using the identify() function of Tkinter我自己提出了一个解决方案,使用 Tkinter 的identify() function
  • Another user proposed to use the Tkinter callback <ButtonRelease-1> which is much more appropriate另一位用户建议使用更合适的 Tkinter 回调<ButtonRelease-1>
  • Finally, a third user focused his answer on using the Tkinter callback <<TreeviewSelect>> , which is for sure the best option最后,第三位用户将他的答案集中在使用 Tkinter 回调<<TreeviewSelect>>上,这肯定是最好的选择

It is because the selection is not set yet when the <Button-1> (it is the same as <ButtonPress-1> , ie when the mouse button 1 is pressed and not released ) event callback is called.这是因为在调用<Button-1> (它与<ButtonPress-1>相同,即当鼠标按钮 1被按下但未释放时)事件回调时尚未设置选择。

You should bind on <ButtonRelease-1> or <<TreeviewSelect>> instead as the selection is set when the event callback is being executed.您应该绑定在<ButtonRelease-1><<TreeviewSelect>>上,因为在执行事件回调时设置了选择。

The reason it doesn't work the way you expect is because your custom single-click binding happens before the default behavior.它不能按您期望的方式工作的原因是您的自定义单击绑定发生在默认行为之前。 So, when your single-click is processed, that happens before an item is selected.因此,在处理您的单击时,会发生在选择项目之前。 The second time you click, your function will print the previously selected item.第二次单击时,您的 function 将打印之前选择的项目。

If you want to have a function called when an item is selected, you should bind to <<TreeviewSelect>> , which will fire immediately after the user selects an item with a single click or via the keyboard.如果您想在选择项目时调用 function ,则应绑定到<<TreeviewSelect>> ,它将在用户单击或通过键盘选择项目后立即触发。

The default behavior of a treeview supports selecting multiple items at once, so the following code will print out the text of all of the selected items as a list, even if only a single item is selected. treeview 的默认行为支持一次选择多个项目,因此以下代码将打印出所有选定项目的文本作为列表,即使只选择了一个项目。 You can, of course, modify this to only print out the first selected item if you so desire.当然,如果您愿意,您可以将其修改为仅打印出第一个选定的项目。

def print_element(event):
    tree = event.widget
    selection = [tree.item(item)["text"] for item in tree.selection()]
    print("selected items:", selection)

tree.bind("<<TreeviewSelect>>", print_element)

Why it doesn't work为什么它不起作用

When you click an item in a treeview, that item is still not in a SELECTED status in the moment the callback is activated.当您单击 treeview 中的项目时,在激活回调的那一刻,该项目仍不处于 SELECTED 状态。 You are changing the status in that very moment.在那一刻,你正在改变状态。

Using a double-click, the first click change the status, and at the second click you are activating your callback, so the status has already been changed.使用双击,第一次单击更改状态,第二次单击时您正在激活回调,因此状态已经更改。

How can it work它如何工作

Kudos to this website这个网站点赞

In short,简而言之,

def print_element(event):
    print(my_treeview.identify('item', e.x, e.y))
my_treeview.bind("<Button-1>", print_element)

This time, print_element() will check the coordinates of the mouse, and will discover the selected item check what is under the mouse.这一次, print_element()将检查鼠标的坐标,并会发现选中的项目检查鼠标下方的内容。 Nice and clean!又好又干净!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM