【发布时间】:2016-05-01 12:57:14
【问题描述】:
我想在循环中创建函数,具体取决于循环变量(用于 PyQT),但这些函数并没有像我想要的那样“取消引用”循环变量。 (我不知道正确的术语,所以请原谅我的草率。)这是一个简单的例子:
a = [1, 2, 3, 4]
b = []
for item in a:
func = lambda: print(item)
b.append(func)
print(a)
for func in b:
func()
我希望b 是一个函数列表,每个函数都打印a 的相应元素(在定义时,如果稍后修改a,它们不应更改)。正如链接中所建议的,func = lambda item=item: print(item) 修复了这个简单的案例,但我无法让我的 PyQT 案例使用相同的修复:
import sys
import xml.etree.ElementTree as ET
from PyQt4 import QtCore, QtGui
class Main(QtGui.QMainWindow):
def __init__(self, parent=None):
QtGui.QMainWindow.__init__(self, parent)
self.tree = ET.fromstring('<root><a>1</a><a>2</a><a>3</a><a>4</a></root>')
self.create_widgets()
self.w = None
def create_widgets(self):
self.buttons = []
# THIS DOESN'T WORK
for value in self.tree.findall('a'):
button = QtGui.QPushButton(value.text)
button.clicked.connect(lambda x=value: self.print_text(x))
self.buttons.append(button)
# THIS DOES WORK:
#values = []
#for value in self.tree.findall('a'):
# values.append(value)
#button = QtGui.QPushButton(values[0].text)
#button.clicked.connect(lambda: self.print_text(values[0]))
#self.buttons.append(button)
#button = QtGui.QPushButton(values[1].text)
#button.clicked.connect(lambda: self.print_text(values[1]))
#self.buttons.append(button)
#button = QtGui.QPushButton(values[2].text)
#button.clicked.connect(lambda: self.print_text(values[2]))
#self.buttons.append(button)
#button = QtGui.QPushButton(values[3].text)
#button.clicked.connect(lambda: self.print_text(values[3]))
#self.buttons.append(button)
box = QtGui.QHBoxLayout()
for i in self.buttons:
box.addWidget(i)
central_widget = QtGui.QWidget()
central_widget.setLayout(box)
self.setCentralWidget(central_widget)
def print_text(self, value):
print(value)
print(value.text)
if __name__ == "__main__":
app = QtGui.QApplication(sys.argv)
myapp = Main()
myapp.show()
sys.exit(app.exec_())
我想传递一个xml.etree 元素,但如果我使用 lambda 函数,我得到的只是False。通过显式创建每个按钮,一切正常。
【问题讨论】:
-
FWIW,
b中的函数 不 必须打印a的最后一个元素:它们实际上打印item的当前值调用,假设您在与创建它们相同的范围内调用它们。看看如果你把item = 42放在for func in b:循环之前会发生什么。 -
Jellby,我冒昧地清理了你的问题。请仔细检查并确保我的编辑没有太大变化。
标签: python pyqt4 name-binding