wxPython:具有动态数据的 PopupMenu

wxPython: PopupMenu with dynamic data

我有下面的代码。 最终目标是 PopupMenu 的内容可以从您单击时延迟。 内容将从文件中加载并放入选项中。 这样可行。 我将问题限制在下面的代码中。 预期的是,当您在框架中右键单击时,您会得到一个带有 2 个选项“menu1”和“menu2”的 PopupMenu。这样可行。 如果你 select “menu 1”,那么应该打印“Command 1”,对于“menu2”,“Command 2” 但是这两个选项都会打印“Command 2”。

有什么帮助吗?

import wx


def on_right_click(event):
    menu = wx.Menu()
    options = [{'msg': 'menu1', 'cmd': 'command 1'},
               {'msg': 'menu2', 'cmd': 'command 2'}]
    for option in options:
        menu_item = menu.Append(wx.ID_ANY, option['msg'])
        menu.Bind(
            event=wx.EVT_MENU,
            handler=lambda x: print(option['cmd']),
            source=menu_item
        )
    frame.PopupMenu(menu, event.GetPosition())
    menu.Destroy()


app = wx.App()
frame = wx.Frame(parent=None, title='Hello World')
frame.Bind(wx.EVT_RIGHT_DOWN, on_right_click)

frame.Show()
app.MainLoop()

lambda 中的变量值是在执行时计算的,因此返回值始终是最后一个值的结果。
您可以通过使用索引并将其增加到无效索引值来对此进行测试,所有 lambda 都会因索引错误而失败。
答案是扩展您的 lambda 参数以修复该值。
例如

import wx

def on_right_click(event):
    menu = wx.Menu()
    options = [{'msg': 'menu1', 'cmd': 'command 1'},
               {'msg': 'menu2', 'cmd': 'command 2'},
               {'msg': 'menu3', 'cmd': "I can't believe"},
               {'msg': 'menu4', 'cmd': "it's not butter"}]
    for option in options:
        menu_item = menu.Append(wx.ID_ANY, option['msg'])
        menu.Bind(
            event=wx.EVT_MENU,
            handler=lambda x, current_cmd = option['cmd']: print(current_cmd),
            source=menu_item
        )
    frame.PopupMenu(menu, event.GetPosition())
    menu.Destroy()


app = wx.App()
frame = wx.Frame(parent=None, title='Right Click to Test')
frame.Bind(wx.EVT_RIGHT_DOWN, on_right_click)

frame.Show()
app.MainLoop()

查看相关 post:position in a list with bind and wxpython