我正在建立一个GUI,您可以在其中按下按钮来隐藏元素。为了构建此功能,我遍历了dict
包含按钮和元素的,并用于lambda
连接方法并传递相应的参数。但是由于某种原因,这不能正常工作。所有lambda
功能都只使用最后一个参数,我觉得这很奇怪。这里发生了什么?lambda
循环中的所有都指向同一对象并被连续覆盖吗?对于我为什么会是这种情况,这真的没有任何意义。
我发现的解决方法是functools.partial
改用,但我仍然想知道为什么使用lambda
不起作用。
这是一个例子:
import sys
from functools import partial
from PyQt5.QtCore import pyqtSlot
from PyQt5.QtWidgets import QApplication, QDialog, QPushButton, QLabel, \
QVBoxLayout
class Test(QDialog):
def __init__(self):
super().__init__()
lay = QVBoxLayout(self)
self.setLayout(lay)
button1 = QPushButton('Button1')
label1 = QLabel('Button1')
button2 = QPushButton('Button2')
label2 = QLabel('Button2')
lay.addWidget(button1)
lay.addWidget(label1)
lay.addWidget(button2)
lay.addWidget(label2)
hide_buttons = {
button1: label1,
button2: label2,
}
for button, label in hide_buttons.items():
# for some reason, this passes on the wrong arguments!
button.clicked.connect(lambda: self.hide_label(button, label))
# button.clicked.connect(partial(self.hide_label, button, label))
@pyqtSlot(QPushButton, QLabel)
def hide_label(self, button, label):
print(button.text(), label.text())
label.hide() if label.isVisible() else label.show()
if __name__ == '__main__':
app = QApplication(sys.argv)
dialog = Test()
dialog.show()
sys.exit(app.exec_())
问题是,当lambda表达式得到执行,他们将使用的电流值button
和label
,这是他们最后的循环过程中得到的。
在lambda被定义(而不执行)时捕获变量值的常见技巧是使用默认参数,因为它们总是在定义时求值:
for button, label in hide_buttons.items():
button.clicked.connect(lambda _, button=button, label=label: self.hide_label(button, label))
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句