Treectrl Events

I have a TreeCtrl object for which I want to implement a context menu n right-click. On Windows everything works but on Linux I have a problem:

On Linux, the wx.EVT_TREE_ITEM_RIGHT_CLICK method does not get called when I right-click, instead the wx.EVT_TREE_SEL_CHANGED gets called. If I remove the binding for wx.EVT_TREE_SEL_CHANGED the right-click method does get called.

I have tried using EVT_LEFT_UP and EVT_LEFT_UP instead of SEL_CHANGED but it makes no difference.

I have been searching for a couple of days to try and find out what is happening but cannot find anything relevant.

Any help gratefully received!

here is my code

        self.Bind(
                wx.EVT_TREE_SEL_CHANGED,
                self.on_item_selected,
                self._tree
                )
        self.Bind(
                wx.EVT_TREE_ITEM_ACTIVATED,
                self.on_item_activated,
                self._tree
                )
        self.Bind(
                wx.EVT_TREE_ITEM_RIGHT_CLICK,
                self.on_tree_right_click,
                self._tree
                )

When I run the code below using wxPython 4.2.1 gtk3 (phoenix) wxWidgets 3.2.4 + Python 3.12.3 + Linux Mint 22 and right click on an item in the TreeCtrl, both the EVT_TREE_SEL_CHANGED and EVT_TREE_ITEM_RIGHT_CLICK do get triggered and the popup menu is displayed.

import wx

class MyPanel(wx.Panel):
    def __init__(self, parent):
        wx.Panel.__init__(self, parent)
        self.tree = wx.TreeCtrl(self)
        self.root = self.tree.AddRoot("Root")
        self.tree.SetItemData(self.root, None)
        for x in range(8):
            self.tree.AppendItem(self.root, f"Tree Item {x}")
        self.tree.Expand(self.root)

        sizer = wx.BoxSizer(wx.VERTICAL)
        sizer.Add(self.tree, 1, wx.EXPAND, 0)
        self.SetSizer(sizer)

        self.tree.Bind(wx.EVT_TREE_SEL_CHANGED, self.OnTreeSelection)
        self.tree.Bind(wx.EVT_TREE_ITEM_RIGHT_CLICK, self.OnTreeItemRightClick)

        self.createPopupMenu()

    def createPopupMenu(self):
        self.popup_menu = wx.Menu()
        for i in range(3):
            label = f"Menu Item {i+1}"
            item = self.popup_menu.Append(-1, label)
            self.Bind(wx.EVT_MENU, self.OnPopupItemSelected, item)

    def OnPopupItemSelected(self, evt):
        item = self.popup_menu.FindItemById(evt.GetId())
        text = item.GetItemLabelText()
        print(f"Menu item '{text}' selected")

    def OnTreeSelection(self, evt):
        print(f"Selected: '{self.tree.GetItemText(evt.GetItem())}'")

    def OnTreeItemRightClick(self, evt):
        pos = evt.GetPoint()
        self.PopupMenu(self.popup_menu, pos)


class MyFrame(wx.Frame):
    def __init__(self, parent):
        wx.Frame.__init__(self, parent)
        self.panel = MyPanel(self)
        self.Bind(wx.EVT_CLOSE, self.OnClose)

    def OnClose(self, _evt):
        self.Destroy()


if __name__ == '__main__':
    app = wx.App()
    frame = MyFrame(None)
    frame.Show()
    app.MainLoop()

Works perfectly. Thank you!
I need to read up on the difference between self.Bind(… item) and self.item.Bind(…)
Paul