我有一个字符串列表,并希望为每个字符串创建一个菜单项。当用户单击其中一个条目时,将始终使用字符串作为参数调用相同的函数。经过一些尝试和研究,我想出了这样的东西:
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_())现在的问题是,每个菜单项都将打印相同的输出:"Item 3“,而不是相应的输出。我很感谢任何关于我如何做好这件事的想法。谢谢。
发布于 2009-07-09 06:10:54
您遇到了在Python中经常被称为“作用域问题”的问题(可能并不是完全老生常谈) --绑定延迟(调用时的词法查找),而您希望早一点(在def-time时)。因此,您现在拥有:
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值)是在默认时间一次性计算的。添加一个级别的函数嵌套(例如,一个双lambda)也可以,但在这里有点夸张!-)
您也可以选择使用functools.partial(self.doStuff, item) (当然,顶部有一个import functools ),这是另一个很好的解决方案,但我认为我会使用最简单(也是最常见)的“参数的假默认值”习惯用法。
发布于 2009-07-08 22:13:07
这应该是可行的,但我很确定还有一种更好的方法,但我现在记不起来了。
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)https://stackoverflow.com/questions/1100775
复制相似问题