如何向事件回调传递额外参数?

6

是否可以向事件回调函数传递额外的参数?

例如,如果我的事件绑定如下:

self.Bind(wx.EVT_BUTTON, self.do_something, self.button) 

我该如何将参数传递给我的方法?
self.do_something(self,event,arguments):
    """do something with arguments"""
    pass

可能是重复的问题 是否可以将参数传递给事件绑定? - ecatmur
这个回答解决了你的问题吗?Python中如何将参数传递给函数指针参数? - user202729
4个回答

9
使用 functools.partial 或一般情况下使用 lambda 表达式。部分形式如下:
functools.partial(self.do_something, args)

请注意,在这种情况下,event参数将会在参数列表的末尾传递。相应的lambda表达式形式如下:
lambda event: self.do_something(args, event)

4

使用lambda:

self.Bind(wx.EVT_BUTTON, lambda event, args=args: self.do_something(event, args), self.button) 

self.do_something(self,event,arguments):
    """do something with arguments"""
    pass

如果你在for循环中使用lambda,可能会出现问题。我更喜欢使用functools.partial方法。 - FogleBird
1
@FogleBird,如果你写成lambda event: self.do_something(event, args)而不是lambda event, args=args: self.do_something(event, args)(注意args=args),那么代码可能会出现混乱。 - warvariuc

1

不清楚您何时想提供这些参数,但如果您想在 Bind 时间提供它们(以便您可以有一个支持多种用途的 do_something),那么您可以使用 functools.partial

def do_something(self, arg, event):
  pass

self.Bind(wx.EVT_BUTTON, functools.partial(self.do_something, arg), self.button)

然后当调用do_something时,它将使用您传递给partialarg以及回调传递的事件一起被调用。


我忘记了那种方式。我只是自己使用lambda。 - Mike Driscoll

1
使用lambda函数。在wxPython wiki上有一些相关文档。我也在我的lambda教程中写了一些关于它的内容。这是我在写那篇文章时创建的一个简单示例(也包含在文章中):
import wx

########################################################################
class DemoFrame(wx.Frame):
    """
    Frame that holds all other widgets
    """

    #----------------------------------------------------------------------
    def __init__(self):
        """Constructor"""        
        wx.Frame.__init__(self, None, wx.ID_ANY, 
                          "wx lambda tutorial",
                          size=(600,400)
                          )
        panel = wx.Panel(self)

        button8 = wx.Button(panel, label="8")
        button8.Bind(wx.EVT_BUTTON, lambda evt, name=button8.GetLabel(): self.onButton(evt, name))
        button10 = wx.Button(panel, label="10")
        button10.Bind(wx.EVT_BUTTON, lambda evt, name=button10.GetLabel(): self.onButton(evt, name))

        sizer = wx.BoxSizer(wx.HORIZONTAL)
        sizer.Add(button8, 0, wx.ALL, 5)
        sizer.Add(button10, 0, wx.ALL, 5)
        panel.SetSizer(sizer)

    #----------------------------------------------------------------------
    def onButton(self, event, buttonLabel):
        """"""
        print "You pressed the %s button!" % buttonLabel

# Run the program
if __name__ == "__main__":
    app = wx.App(False)
    frame = DemoFrame().Show()
    app.MainLoop()

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接