【问题标题】:How do I pass additional arguments to an event callback?如何将其他参数传递给事件回调?
【发布时间】:2012-06-30 01:17:54
【问题描述】:

是否可以将其他参数传递给事件回调?

例如,如果我的事件绑定看起来像这样;

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

如何将参数传递给我的方法?

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

【问题讨论】:

标签: python wxpython


【解决方案1】:

使用 lambda 函数。 wxPython wiki 上有一些关于此的文档。我还在我的lambda tutorial 中写过它。这是我在写这篇文章时创建的蹩脚示例(文章中也有):

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

【讨论】:

    【解决方案2】:

    不清楚何时提供这些参数,但如果你想在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。
    【解决方案3】:

    使用functools.partial,或者在一般情况下使用lambda expression

    部分形式是

    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,如果你写 lambda event: self.do_something(event, args) 而不是 lambda event, args=args: self.do_something(event, args),就会发生混乱(注意 args=args
      猜你喜欢
      • 2019-12-21
      • 1970-01-01
      • 2019-08-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-11-22
      相关资源
      最近更新 更多