Reputation: 784
When you want to select an item in a Treeview, you usually use the double-click:
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. 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.
identify()
function of Tkinter<ButtonRelease-1>
which is much more appropriate<<TreeviewSelect>>
, which is for sure the best optionUpvotes: 2
Views: 7827
Reputation: 385830
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.
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.
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. 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)
Upvotes: 5
Reputation: 46669
It is because the selection is not set yet when the <Button-1>
(it is the same as <ButtonPress-1>
, i.e. when the mouse button 1 is pressed and not released) event callback is called.
You should bind on <ButtonRelease-1>
or <<TreeviewSelect>>
instead as the selection is set when the event callback is being executed.
Upvotes: 1
Reputation: 784
When you click an item in a treeview, that item is still not in a SELECTED status in the moment the callback is activated. 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.
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. Nice and clean!
Upvotes: 0