我有一个字符串列表,并希望创建为每个字符串的菜单项。当用户点击一个条目,总是相同的功能应与字符串作为参数调用。一些尝试和研究后,我想出了这样的事情:

import sys
from PyQt4 import QtGui, QtCore

class MainWindow(QtGui.QMainWindow):
    def __init__(self):
        QtGui.QMainWindow.__init__(self)
        self.menubar = self.menuBar()
        menuitems = ["Item 1","Item 2","Item 3"]
        menu = self.menubar.addMenu('&Stuff')
        for item in menuitems:
            entry = menu.addAction(item)
            self.connect(entry,QtCore.SIGNAL('triggered()'), lambda: self.doStuff(item))
            menu.addAction(entry)
        print "init done"

    def doStuff(self, item):
        print item

app = QtGui.QApplication(sys.argv)
main = MainWindow()
main.show()
sys.exit(app.exec_())

现在的问题是,每个菜单项将打印相同的输出:“项目3”,而不是相应的一个。我很感激我如何能得到这个权利的任何想法。感谢。

有帮助吗?

解决方案

您要去见什么Python中被通常称为(也许不完全是迂腐,正确;-)为“范围界定问题” - 绑定晚(在通话时词汇查找),而你想它早期(在DEF-时间)。那么,你现在有:

    for item in menuitems:
        entry = menu.addAction(item)
        self.connect(entry,QtCore.SIGNAL('triggered()'), lambda: self.doStuff(item))

尝试代替:

    for item in menuitems:
        entry = menu.addAction(item)
        self.connect(entry,QtCore.SIGNAL('triggered()'), lambda item=item: self.doStuff(item))

此“预测”的结合,由于默认值(作为一个item这里)获得计算一次一个为所有在DEF-时间。添加嵌套函数一个等级(例如双拉姆达)工作过,但它是一个有点矫枉过正这里 - !)

您可以选择使用functools.partial(self.doStuff, item)(与课程顶部的import functools),这是另一种精解,但我想我会去的最简单的(最常见)“假默认值参数”的成语。

其他提示

这应该工作,但我敢肯定有,我现在不能回忆起一个更好的办法。

def do_stuff_caller(self, item):
    return lambda: self.doStuff(item)

...
self.connect(entry, QtCore.SIGNAL('triggered()'), self.do_stuff_caller(item))

修改: 较短的版本,这还不是什么,我想...也许这是用另一种语言? :)

(lambda x: lambda self.do_stuff(x))(item)
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top