可以在事件绑定中传递参数吗?

33 投票
2 回答
20995 浏览
提问于 2025-04-11 09:23

我在其他地方没有找到答案,而且这个问题似乎还没有在StackOverflow上被提问过。

在wxPython中创建事件绑定时,能不能传递额外的参数给事件?比如,这里是普通的写法:

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())

但是有没有办法让这个方法接收另一个参数呢?这样这个方法就能知道是哪个控件在调用它,但仍然返回相同的值?

这样可以大大减少复制粘贴相同代码但调用者不同的情况。

2 个回答

14

最好的方法是创建一个事件处理程序的生成器,比如:

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

现在你可以用下面的方式来绑定它:

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

你可以使用一个叫做“lambda”的东西,或者其他函数,来包装你的方法,并传递另一个参数,这个参数和WX没有关系。

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())

如果你想减少输入的代码量,你也可以试试一些自动化的小技巧,比如:

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')

撰写回答