开发者

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

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜