wxPython not binding callbacks to events properly
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(w开发者_开发百科x.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?
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)
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)
精彩评论