gpt4 book ai didi

python-2.7 - pyqt4正确连接QCheckbox状态

转载 作者:行者123 更新时间:2023-12-02 01:42:34 25 4
gpt4 key购买 nike

我有一个 QWidget 类,其中包含一个 QLabel。该类在 QVBox 中生成 QCheckbox。我正在尝试将每个复选框连接到 nameCheckBox 方法,该方法将更新 QLabel 以显示最后一个选中框的标题。然而,当一个复选框被有效地取消/选中时,它总是被检测为未选中。此外,返回的名称始终是最后创建的复选框。我不明白我的错误在哪里。这是我的代码:

import sys
from PyQt4 import QtCore
from PyQt4.QtGui import *
from MenusAndToolbars import MenuWindow

class checkBoxWidget(QWidget):
"""
This widget has a QVBox which contains a QLabel and QCheckboxes.
Qcheckbox number is connected to the label.
"""

def __init__(self):
QWidget.__init__(self)
self.__setUI()

def __setUI(self):
vbox = QVBoxLayout(self)
label = QLabel('Last clicked button: ' + "None", self)

vbox.addWidget(label)

listCB = []

for i in range(10):
listCB.append( QCheckBox('CheckBox Nb. ' + str(i+1) ) )
listCB[i].stateChanged.connect(lambda: self.nameCheckBox(label, listCB[i]) )
vbox.addWidget( listCB[i] )


def nameCheckBox(self, label, checkBox):
if checkBox.isChecked():
print "Checked: " + checkBox.text()
label.setText('Last clicked button: ' + checkBox.text())
else:
print "Unchecked: " + checkBox.text()



def main():
app = QApplication(sys.argv)
window = QMainWindow()
window.setCentralWidget( checkBoxWidget() )
window.show()
#window = WidgetWindow()
sys.exit(app.exec_())

if __name__ == "__main__":
main()

编辑 1

我找到了几个“黑客”解决方案。

解决方案 1:创建一个回调函数就可以了:

def callBack(self, list, index, label):
return lambda: self.nameCheckBox(label, list[index])

然后我以这种方式连接 QCheckbox().stateChanged 信号:

listCB[i].stateChanged.connect( self.callBack(listCB, i, label) )

解决方案 2:使用 partial 模块:

首先我们导入模块:

from functools import partial

那么信号连接是这样完成的:

listCB[i].stateChanged.connect( partial( self.nameCheckBox, label, listCB[i] ) )

但是我想在一行中使用 lambda 表达式。特别是我想了解它是如何工作的。通过链接,我了解到问题与 lambda 范围有关。正如 Oleh Prypin 建议的那样,我写道:

listCB[i].stateChanged.connect(lambda i=i: self.nameCheckBox(label,  listCB[i]) )

这里变量 i 是一个新变量。但是我原来的问题仍然存在。然后我出于好奇尝试了这个:

listCB[i].stateChanged.connect( lambda label=label, listCB=listCB, i=i: self.nameCheckBox(label, listCB[i] ) )

但是我得到以下错误:

Traceback (most recent call last):
Checked: CheckBox Nb. 2
File "Widgets.py", line 48, in <lambda>
listCB[i].stateChanged.connect( lambda label=label, listCB=listCB, i=i: self.nameCheckBox(label, listCB[i] ) )
File "Widgets.py", line 59, in nameCheckBox
label.setText('Last clicked button: ' + checkBox.text())
AttributeError: 'int' object has no attribute 'setText'

这里似乎在未选中/选中时识别了正确的按钮。然而,新的 label 变量似乎被视为一个 int?这里发生了什么?

最佳答案

lambda: self.nameCheckBox(label,  listCB[i])

绑定(bind)到变量 i,意味着 i 的值将是调用 lambda 时的值,而不是创建时的值,也就是说,在这个大小写,总是 9。
可能的修复:

lambda i=i: self.nameCheckBox(label, listCB[i])

有很多关于这个主题的一般信息。起点:Google search ,另一个问题Creating lambda inside a loop .


不幸的是,我的修复没有奏效,因为该信号为其调用的函数提供了参数 checked,根据检查状态用 0 或 2 覆盖默认参数。这将起作用(忽略不需要的参数):

lambda checked, i=i: self.nameCheckBox(label, listCB[i])

这是编写该类的另一种方法:

class CheckBoxWidget(QWidget):
def __init__(self):
QWidget.__init__(self)
self.setupUi()

def setupUi(self):
vbox = QVBoxLayout(self)
self.label = QLabel("Last clicked button: None")

vbox.addWidget(self.label)

for i in range(10):
cb = QCheckBox("CheckBox Nb. " + str(i+1))
cb.stateChanged.connect(self.nameCheckBox)
vbox.addWidget(cb)

def nameCheckBox(self, checked):
checkBox = self.sender()
if checked:
print("Checked: " + checkBox.text())
self.label.setText("Last clicked button: " + checkBox.text())
else:
print("Unchecked: " + checkBox.text())

关于python-2.7 - pyqt4正确连接QCheckbox状态,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27636773/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com