Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does my ttk.Treeview click handler return the wrong item on tree.focus()?

I have a simple script using a ttk.Treeview instance that I'm populating with the contents of a file system tree. I want to perform a certain operation when (leaf) items are clicked so I configured a handler like so:

self.tree.tag_bind('#entry', '<1>', self.onClick)

In the method onClick I am simply printing out the item that was clicked, like so:

def onClick(self, event):
    item_id = str(self.tree.focus())
    print 'Selected item was %s' % item_id
    item = self.tree.item(item_id)
    flag = '#another_tag' in item['tags']
    print '  flag = %s' % flag

I'm finding that the messages are lagging the clicks by one. So my first click gets a random value (looks like the root of the tree), and then the n-th click prints out the values for the (n-1)th item that was clicked.

They were inserted like so: tree.insert(parent_id, 'end', id, text=id, tags=['#entry'])

Anyone know if this is a bug in Tkinter or something that I'm doing wrong?

This appears to be an issue on both Ubuntu Natty as well as OS X Lion (using the default pre-installed versions of Python and Tkinter)

like image 464
scorpiodawg Avatar asked Aug 19 '12 02:08

scorpiodawg


People also ask

How do I edit a Treeview in Python?

The Treeview widget items can be edited and deleted by selecting the item using tree. selection() function. Once an item is selected, we can perform certain operations to delete or edit the item.

What is IID in Treeview?

The iid argument stands for item identifier which is unique for each item, and you can give it the value you want.

How do you insert data into Treeview?

We can use insert() to add one parent of main node ( row ) to the Treeview. Here we have one student record table ( no database here ) and one record is already available. Below the Treeview, input boxes and options are available to add nodes to this Treeview using insert() method.

How do I disable Treeview in Python?

The Treeview widget is used to display a list of items with more than one feature in the form of columns. By default, the listed items in a Treeview widget can be selected multiple times, however you can disable this feature by using selectmode="browse" in the Treeview widget constructor.


1 Answers

This is the way Tkinter is designed to work. Bindings on a widget are processed before bindings on the widget class. It is the bindings on the widget class that set the selected item. This makes it really easy to override the default bindings, at the expense of making it slightly harder to augment default bindings.

This has been asked a few times on this site. Search for "bindtags" on this site; bindtags are the mechanism that controls the order of event processing.

In the specific case of the treeview widget, I recommend binding to the <<TreeviewSelect>> event, which will be processed after the selection has been set. You can then use the tag_has method to determine what sort of node was clicked on.

like image 97
Bryan Oakley Avatar answered Oct 13 '22 09:10

Bryan Oakley