Using the same handler for multiple wx.TextCtrls?
Question: I'm having a bit of trouble with a panel that has two wxPython TextCtrls in
it. I want either an EVT_CHAR or EVT_KEY_UP handler bound to both controls,
and I want to be able to tell which TextCtrl generated the event. I would
think that event.Id would tell me this, but in the following sample code it's
always 0. Any thoughts? I've only tested this on OS X.

This code simply checks that both TextCtrls have some text in them before
enabling the Done button

    
    
    import wx
    
    class MyFrame(wx.Frame):
        def __init__(self, parent, ID, title):
            wx.Frame.__init__(self, parent, ID, title,
                             wx.DefaultPosition, wx.Size(200, 150))
            self.panel = BaseNameEntryPanel(self)
    
    class BaseNameEntryPanel(wx.Panel):
        def __init__(self, parent):
            wx.Panel.__init__(self, parent, -1)
    
            self.entry = wx.TextCtrl(self, wx.NewId())
            self.entry2 = wx.TextCtrl(self, wx.NewId())
    
            self.donebtn = wx.Button(self, wx.NewId(), "Done")
            self.donebtn.Disable()
    
            vsizer = wx.BoxSizer(wx.VERTICAL)
    
            vsizer.Add(self.entry, 1, wx.EXPAND|wx.GROW)
            vsizer.Add(self.entry2, 1, wx.EXPAND|wx.GROW)
            vsizer.Add(self.donebtn, 1, wx.EXPAND|wx.GROW)
            self.SetSizer(vsizer)
            self.Fit()
            self.entry.Bind(wx.EVT_KEY_UP, self.Handle)
            self.entry2.Bind(wx.EVT_KEY_UP, self.Handle)
    
    
        def Handle(self, event):
            keycode = event.GetKeyCode()
            print keycode, event.Id # <- event.Id is always 0!
    
            def checker(entry):
                return bool(entry.GetValue().strip())
    
            self.donebtn.Enable(checker(self.entry) and checker(self.entry2))
    
    
    
    class MyApp(wx.App):
        def OnInit(self):
            frame = MyFrame(None, -1, "Hello from wxPython")
            frame.Show(True)
            self.SetTopWindow(frame)
            return True
    
    app = MyApp(0)
    app.MainLoop()
    


Answer: You could try `event.GetId()` or `event.GetEventObject()` and see if either of
these work.

Another approach to this is to use lambda or functools.partial to effectively
pass a parameter to the handler. So, for example, sub in the lines below into
your program:

    
    
            self.entry.Bind(wx.EVT_KEY_UP, functools.partial(self.Handle, ob=self.entry))
            self.entry2.Bind(wx.EVT_KEY_UP, functools.partial(self.Handle, ob=self.entry2))
    
        def Handle(self, event, ob=None):
                print ob
    

And then ob will be either `entry` or `entry2` depending on which panel is
clicked. But, of course, this shouldn't be necessary, and GetId and
GetEventObject() should both work -- though I don't (yet) have a Mac to try
these on.

