从字符串列表创建PyQt的菜单
-
11-09-2019 - |
题
我有一个字符串列表,并希望创建为每个字符串的菜单项。当用户点击一个条目,总是相同的功能应与字符串作为参数调用。一些尝试和研究后,我想出了这样的事情:
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)
不隶属于 StackOverflow