Search code examples
pythoneventswxpython

How do I handle an item selection event in wxpython EditableListBox?


I have an EditableListBox in a wxpython app. I want an event to trigger whenever the user clicks an item in the box. I can bind a function to EVT_LIST_ITEM_SELECTED, but this seems to break the edit buttons in the list box in a very bizarre way. The up arrow is disabled and doesn't do anything, and the down arrow only swaps the first to items in the list, regardless of what I have selected. Here is a small example showing the behavior:

import wx
import wx.gizmos

class MyApp(wx.App):
    def OnInit(self):
        frame = wx.Frame(None, -1, "Hello")

        self.gui_list = wx.gizmos.EditableListBox(frame, wx.ID_ANY, 'Listbox Name', style=wx.gizmos.EL_ALLOW_DELETE)

        self.gui_list.Strings = ["one","two","red","blue"]

        self.text = wx.StaticText(frame, wx.ID_ANY, "Text Here")

        self.gui_list.Bind(wx.EVT_LIST_ITEM_SELECTED, self.change_text)

        self.gui_list.Show(True)
        self.text.Show(True)
        box = wx.BoxSizer(wx.VERTICAL)
        box.Add(self.gui_list)
        box.Add(self.text)
        frame.SetSizer(box)
        frame.Layout()
        frame.Show(True)
        self.SetTopWindow(frame)
        return True

    def change_text(self, event):
        self.text.SetLabel(event.GetText())

app = MyApp(0)
app.MainLoop()

I have no idea what's going on here. Is there a way to catch the click event without destroying the edit buttons in EditableListBox?


Solution

  • When there are problems with controls derived from standard controls it is always a good idea to try to deactivate self-defined bindings (because they might overwrite some event handlers from the underlying control).

    When uncommenting the line with the binding to change_text, the control behaves normally. In this case it helps to skip the event to allow the control itself to react on wx.EVT_LIST_ITEM_SELECTED events.

    def change_text(self, event):
        self.text.SetLabel(event.GetText())
        # skip event to allow further processing of event
        event.Skip()