Question

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)

Was it helpful?

Solution

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.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top