在wxPython中,如何绑定到循环中的独立对象,包括参数?

2024-03-28 20:23:00 发布

您现在位置:Python中文网/ 问答频道 /正文

我不确定我是否恰当地表达了这个问题,代码可能会更清晰。你知道吗

我正在给WxPython应用程序添加一个非常简单的插件系统,插件选项被简单地添加到一个子菜单中,一旦它们被单击,插件的操作就会被执行。我是wx的新手,所以可能有一些简单的事情我做错了,所以我很乐意得到通知。你知道吗

以下代码按预期工作,并调用单击菜单选项的插件“performAction”方法。你知道吗

for plugin in self.pluginManager.plugins:
    wxId = wx.NewId()
    plugin_submenu.Append(wxID,plugin.displayName)
    canvas.Bind(wx.EVT_MENU, plugin.performAction)

我还想为plugin操作添加参数,这使我使用lambdas,因为“bind”方法的第二个参数应该是可调用的。这似乎是一个相当不起眼的变化:

for plugin in self.pluginManager.plugins:
    wxId = wx.NewId()
    plugin_submenu.Append(wxID,plugin.displayName)
    canvas.Bind(wx.EVT_MENU, lambda evt, temp=objArgs: plugin.performAction(evt,temp)

this link所述。然而,当我这样做时,无论哪个插件对象被绑定最后一个都会被调用,而不管实际单击的是哪个菜单选项。我真的不知道为什么行为会从第一个代码样本变为第二个,但确实如此,我被难住了。你知道吗

那么,有人知道为什么会发生这种情况吗?我该怎么做才能得到我所期望的行为?你知道吗


Tags: 方法代码inself插件for选项菜单
1条回答
网友
1楼 · 发布于 2024-03-28 20:23:00

你的问题是python的作用域规则。在第一种情况下,您已经将plugin的一个特定实例绑定到画布,在执行此代码时

在第二种情况下,您将一个特定的函数,lambda函数绑定到画布上,同样在执行此代码时。不幸的是,lambda函数引用了一个插件对象,它在事件发生之前不会被实际计算。当您的事件发生时,这段代码将早已执行完毕,您将触发的实际plugin将是最后一个遇到的。你知道吗

“捕获”实际插件实例的一种方法是在lambda定义中捕获它,将其作为额外参数传入:

for plugin in self.pluginManager.plugins:
    wxId = wx.NewId()
    plugin_submenu.Append(wxID,plugin.displayName)
    canvas.Bind(wx.EVT_MENU, lambda evt, p=plugin, temp=objArgs:    
                p.performAction(evt,temp))

不确定我是否对为什么/如何发生这种情况给出了一个很好的解释,但是here是另一个可能有用的解释。你知道吗

相关问题 更多 >