2

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.

  • I proposed a solution myself using the identify() function of Tkinter
  • Another user proposed to use the Tkinter callback <ButtonRelease-1> which is much more appropriate
  • Finally, a third user focused his answer on using the Tkinter callback <<TreeviewSelect>>, which is for sure the best option
5
  • Does this answer your question? tkinter-treeview-click-event-for-selected-item Commented Apr 24, 2020 at 10:04
  • You should bind on <ButtonRelease-1> or <<TreeviewSelect>> instead. Commented Apr 24, 2020 at 10:09
  • @acw1668 I didn't think about using that event in that way. What you suggest is probably the pythonic way to do it. If you leave it an answer, I will accept yours Commented Apr 24, 2020 at 10:26
  • Are you asking how to select an item in a treeview on click? Treeview does that automatically for you. Or, are you asking how to run a function whenever something is selected in the Treeview? Commented Apr 24, 2020 at 13:25
  • @BryanOakley my goal is to obtain a specific value from the selected item, in the same moment it is selected, without a need for the doubleclick Commented Apr 25, 2020 at 18:26

3 Answers 3

5

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)
Sign up to request clarification or add additional context in comments.

Comments

1

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.

1 Comment

I have to pick Bryan answer because he provided a code solution, and focused his answer to TreeviewSelect (I didn't even pay attention to it when you mentioned it). Still, kudos for bringing up ButtonRelease-1
0

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. 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. Nice and clean!

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.