Using lambda function within event binding

In wxPython code, I've got a set of buttons with similar behavior. I want to use a single handler function for all the buttons, and am using a lambda function to set up an extra argument which will indicate some characteristic of the button. I've done this with inline code, but I'm trying to do it in a loop. In the following example, the output to the console always prints an index of 2 (the index for th last button) regardless of which button is pressed. On the other hand, EventObject.GetLabel() does the right thing in each case.

I also constructed a similar, non-gui test case (not included), so I *think* I'm using lambda properly. Any ideas?

#base code borrowed from "wxPython In Action" listing 3.3
import wx

class MouseEventFrame(wx.Frame):
    def __init__(self, parent, id):
        wx.Frame.__init__(self, parent, id, title="Testing", size=(300, 120))
        self.panel = wx.Panel(self)

        for i in range(3):
            self.button = wx.Button(self.panel, label="Button "+str(i), pos=(100, 15 + 20*i ))
            self.Bind(wx.EVT_BUTTON, lambda evt : self.OnSetRank(evt, i), self.button)
            self.button.Bind(wx.EVT_ENTER_WINDOW, self.OnEnterWindow)
            self.button.Bind(wx.EVT_LEAVE_WINDOW, self.OnLeaveWindow)

    def OnSetRank(self, event, index):
        print index
        print event.EventObject.GetLabel()

    def OnEnterWindow(self, event):
        self.button.SetLabel("Over")
        event.Skip()

    def OnLeaveWindow(self, event):
        self.button.SetLabel("Not over")
        event.Skip()

if __name__ == '__main__':
    app = wx.PySimpleApp()
    frame = MouseEventFrame(None, id=-1)
    frame.Show()
    app.MainLoop()

Hello,

···

On Mar 15, 2009, at 12:57 PM, Dave Angel wrote:

class MouseEventFrame(wx.Frame):
  def __init__(self, parent, id):
      wx.Frame.__init__(self, parent, id, title="Testing", size=(300, 120))
      self.panel = wx.Panel(self)

      for i in range(3):
          self.button = wx.Button(self.panel, label="Button "+str(i), pos=(100, 15 + 20*i ))
          self.Bind(wx.EVT_BUTTON, lambda evt : self.OnSetRank(evt, i), self.button)

try:

self.Bind(wx.EVT_BUTTON, lambda evt, index=i: self.OnSetRank(evt, index), self.button)

Cody

Could you get away with just setting the ID of the button?
      for i in range(3):
          self.button = wx.Button(self.panel, id=i, label="Button
"+str(i), pos=(100, 15 + 20*i ))
          self.Bind(wx.EVT_BUTTON, self.OnSetRank, self.button)
          self.button.Bind(wx.EVT_ENTER_WINDOW, self.OnEnterWindow)
          self.button.Bind(wx.EVT_LEAVE_WINDOW, self.OnLeaveWindow)

def OnSetRank(self, event):
    print event.ID

--Mark

···

On Sun, Mar 15, 2009 at 1:09 PM, Cody Precord <codyprecord@gmail.com> wrote:

Hello,

On Mar 15, 2009, at 12:57 PM, Dave Angel wrote:

class MouseEventFrame(wx.Frame):
def __init__(self, parent, id):
wx.Frame.__init__(self, parent, id, title="Testing", size=(300, 120))
self.panel = wx.Panel(self)

 for i in range\(3\):
     self\.button = wx\.Button\(self\.panel, label=&quot;Button &quot;\+str\(i\),

pos=(100, 15 + 20*i ))
self.Bind(wx.EVT_BUTTON, lambda evt : self.OnSetRank(evt, i),
self.button)

try:

self.Bind(wx.EVT_BUTTON, lambda evt, index=i: self.OnSetRank(evt, index),
self.button)

Cody

_______________________________________________
wxpython-users mailing list
wxpython-users@lists.wxwidgets.org
http://lists.wxwidgets.org/mailman/listinfo/wxpython-users