views:

887

answers:

2

I haven't found an answer elsewhere and this doesn't appear to have been asked yet on SO.

When creating an event binding in wxPython, is it possible to pass additional arguments to the event? For example, this is the normal way:

b = wx.Button(self, 10, "Default Button", (20, 20))
        self.Bind(wx.EVT_BUTTON, self.OnClick, b)
def OnClick(self, event):
        self.log.write("Click! (%d)\n" % event.GetId())

But is it possible to have another argument passed to the method? Such that the method can tell if more than one widget is calling it but still return the same value?

It would greatly reduce copy & pasting the same code but with different callers.

+6  A: 

You can always use a lambda or another function to wrap up your method and pass another argument, not WX specific.

b = wx.Button(self, 10, "Default Button", (20, 20))
        self.Bind(wx.EVT_BUTTON, lambda event: self.OnClick(event, 'somevalue'), b)
def OnClick(self, event, somearg):
        self.log.write("Click! (%d)\n" % event.GetId())

If you're out to reduce the amount of code to type, you might also try a little automatism like:

class foo(whateverwxobject):
    def better_bind(self, type, instance, handler, *args, **kwargs):
        self.Bind(type, lambda event: handler(event, *args, **kwargs), instance)

    def __init__(self):
        self.better_bind(wx.EVT_BUTTON, b, self.OnClick, 'somevalue')
Florian Bösch
+3  A: 

The nicest way would be to make a generator of event handlers, e.g.:

def getOnClick(self, additionalArgument):
    def OnClick(self, event):
        self.log.write("Click! (%d), arg: %s\n" 
                         % (event.GetId(), additionalArgument))
    return OnClick

Now you bind it with:

b = wx.Button(self, 10, "Default Button", (20, 20))
b.Bind(wx.EVT_BUTTON, self.getOnClick('my additional data'))
DzinX