wx.TreeCtrl, react to left mouse click on a tree item

Hi,
I have a wx.TreeCtrl and want to react on the left mouse up event. There are several approaches ,e.g. with EVT_LEFT_UP or EVT_MOUSE_EVENTS, but all fails when I click on a tree item. It seems that in that case the event is used internally to change the focus of the tree item and isn't skipped.
I have added a sample program where you can test the behaviour. Just try to perform the left down and the left up mouse event on the same tree item. No "LeftUp" will be printed, which is the problem. On the other hand, if you click elsewhere in the list control a "LeftUp" will appear.

Do you know any workarounds to react on the left mouse up event? I can't use the tree selection changed event, because I only want to react on mouse events.

Some info to my platform:
wxWidgets 2.8.8.1 (wxMSW, unicode, wx-assertions-on, SWIG-1.3.29) Running on Python 2.5.2, Windows XP Pro SP 3

Awaiting your answers
Christian

treectrl.py (1.2 KB)

Christian wrote:

Hi,
I have a wx.TreeCtrl and want to react on the left mouse up event. There are several approaches ,e.g. with EVT_LEFT_UP or EVT_MOUSE_EVENTS, but all fails when I click on a tree item. It seems that in that case the event is used internally to change the focus of the tree item and isn't skipped.
I have added a sample program where you can test the behaviour. Just try to perform the left down and the left up mouse event on the same tree item. No "LeftUp" will be printed, which is the problem. On the other hand, if you click elsewhere in the list control a "LeftUp" will appear.

Do you know any workarounds to react on the left mouse up event? I can't use the tree selection changed event, because I only want to react on mouse events.

My guess is that the native tree widget on windows is capturing the mouse on the left-down event, such that only it will get the left-up event. So what you can do is intercept the whole process instead of just the tail end of it. In other words, catch the left-down yourself and don't call Skip(). You'll need to use HitTest to find the item that is being clicked on, and then select it yourself, but then you should get the left-up since you are not allowing the native widget to take control.

···

--
Robin Dunn
Software Craftsman
http://wxPython.org Java give you jitters? Relax with wxPython!

Robin Dunn wrote:

My guess is that the native tree widget on windows is capturing the mouse on the left-down event, such that only it will get the left-up event. So what you can do is intercept the whole process instead of just the tail end of it. In other words, catch the left-down yourself and don't call Skip(). You'll need to use HitTest to find the item that is being clicked on, and then select it yourself, but then you should get the left-up since you are not allowing the native widget to take control.

That works, in fact. Further I found out, that the event is only catch internally, when TR_MULTIPLE is not set, hence and the reimplementation of the standard behaviour is quite simple.

Thanks for your help!
Christian

PS: Here is my adapted class:

class MyTreeCtrl(wx.TreeCtrl):
    def __init__(self, *args, **kargs):
        wx.TreeCtrl.__init__(self, *args, **kargs)
        self.Bind(wx.EVT_MOUSE_EVENTS, self.OnMouseEvent)
       def OnMouseEvent(self, event):
        if event.LeftDown() and not self.HasFlag(wx.TR_MULTIPLE):
            ht_item, ht_flags = self.HitTest(event.GetPosition())
            if (ht_flags & wx.TREE_HITTEST_ONITEM) != 0:
                self.SetFocus()
                self.SelectItem(ht_item)
            else:
                event.Skip()
        elif event.LeftUp():
            ht_item, ht_flags = self.HitTest(event.GetPosition())
            if (ht_flags & wx.TREE_HITTEST_ONITEM) != 0:
                print "OnMouseEvent -> LeftUp"
        else:
            event.Skip()

In 2024 and Python3+Phoenix, is there a simpler way to react when the user clicks on any item in a tree?