Reputation: 17847
Here's a roughly minimal demonstrative example:
import wx
app = wx.App(False)
frame = wx.Frame(None)
menuBar = wx.MenuBar()
menu = wx.Menu()
menuBar.Append(menu, "&Menu")
frame.SetMenuBar(menuBar)
for name in ['foo','bar','baz']:
menuitem = menu.Append(-1,"&"+name,name)
def menuclick(e):
print(name)
frame.Bind(wx.EVT_MENU, menuclick, menuitem)
frame.Show(True)
app.MainLoop()
The issue is that every menu item, when clicked, prints "baz". Shouldn't the menuclick
function wrap up the appropriate name in its closure and keep the original name around?
Upvotes: 0
Views: 344
Reputation: 7512
After the for loop name
will be "baz", it's value will not go back in time to when you bound the menuclick
to the menu event.
You can get to the menu item name via the event itself like this:
def menuclick(e):
print(menu.FindItemById(e.Id).Label)
Upvotes: 2
Reputation: 17847
I found this solution, by I'm not sure why this works where the inner-def version doesn't:
from functools import partial
def onclick(name,e):
print(name)
for name in ['foo','bar','baz']:
menuitem = menu.Append(-1,"&"+name,name)
frame.Bind(wx.EVT_MENU, partial(onclick,name), menuitem)
Upvotes: 0