views:

256

answers:

1

Hi everyone!
Coming from this question, I have a wxComboCtrl with a custom popup made of a panel with a bunch of radiobuttons.. My problem is that when I open the popup the combo doesn't get keystrokes, because the events get handled by the panel itself.. I'd like to redirect those KeyEvents to the textctrl of the combo, but I can't find a way to get it to work :/
Am I going the wrong way? Should I manually handle the textctrl value as the user presses keys? I think that would be a bit cumbersome though.. Since supposedly the textctrl already knows how to handle those events..

Here's my testcase (wxPython 2.8 on Linux), the "on_key" method should be the culprit:

import wx
import wx.combo

class CustomPopup(wx.combo.ComboPopup):

    def Create(self, parent):
        # Create the popup with a bunch of radiobuttons
        self.panel = wx.Panel(parent)
        sizer = wx.GridSizer(cols=2)
        for x in range(10):
            r = wx.RadioButton(self.panel, label="Element "+str(x))
            r.Bind(wx.EVT_RADIOBUTTON, self.on_selection)
            sizer.Add(r)
        self.panel.SetSizer(sizer)

        # Handle keyevents
        self.panel.Bind(wx.EVT_KEY_UP, self.on_key)

    def GetControl(self):
        return self.panel

    def GetAdjustedSize(self, minWidth, prefHeight, maxHeight):
        return wx.Size(200, 150)

    def on_key(self, evt):
        if evt.GetEventObject() is self.panel:
            # Trying to redirect the key event to the combo.. But this always returns false :(
            print self.GetCombo().GetTextCtrl().GetEventHandler().ProcessEvent(evt)
        evt.Skip()

    def on_selection(self, evt):
        self.Dismiss()
        wx.MessageBox("Selection made")


class CustomFrame(wx.Frame):

    def __init__(self):
        # Toolbar-shaped frame with a ComboCtrl
        wx.Frame.__init__(self, None, -1, "Test", size=(800,50))
        combo = wx.combo.ComboCtrl(self)
        popup = CustomPopup()
        combo.SetPopupControl(popup)

        sizer = wx.BoxSizer(wx.VERTICAL)
        sizer.Add(combo, 0)
        self.SetSizer(sizer)
        self.Layout()

if __name__ == '__main__':
    app = wx.PySimpleApp()
    CustomFrame().Show()
    app.MainLoop()

Edit:
I found these (unresolved) discussions on the same topic..
"ComboCtrl loses keyboard focus when ComboPopup is shown "
"issue using wx.ComboCtrl"

A: 

I've got an answer from Robin Dunn himself on wxpython-users:

Sending low-level events to native widgets like this does not work the way that most people expect it to. You are expecting this to result in the character being added to the text ctrl,but it can't do that because all that ProcessEvent does is send the wx.Event to any bound event handlers and then it stops. It does not go to the next step and convert that event to the equivalent native message and send it on to the native widget. See the "Simulating keyboard events" thread.

It doesn't work especially well on non-Windows platforms, but you could try calling EmulateKeypress instead.

Joril
Robin Dunn is DA MAN!
Jim Carroll