我有一个循环。我创建了一个QCheckBox
并将其放在QTableWidget
单元格中,一切正常。在循环的每个步骤中,我为myslot SLOT调用了一个connect
函数,但只应用了最后一个QCheckBox
实例。我google了很多,发现很多人都有我的问题。我已经应用了他们的解决方案,但问题仍然存在。
for row in xrange(len(uniqueFields)):
instance = QtGui.QCheckBox(uniqueFields[row], findInstance.tableWidget)
print QtCore.QObject.connect(instance,
QtCore.SIGNAL(_fromUtf8("stateChanged (int)")),
lambda: findInstance.projectsInstance.myslot(
"TWCH", findInstance, instance.text(),
instance.checkState(), instance))
findInstance.tableWidget.setRowCount(findInstance.tableWidget.rowCount() + 1)
findInstance.tableWidget.setCellWidget(row, 0, instance)
注意:我的connect
函数返回True
。
如何在枚举所有connect
的循环中创建instances
函数?
答案 0 :(得分:4)
将循环变量放在默认参数中,如下所示:
lambda state, instance=instance: findInstance.projectsInstance.myslot(
"TWCH", findInstance, instance.text(), instance.checkState(), instance)
这将为每个lambda
提供instance
变量的本地副本。
修改强>
这是一个简单的脚本,演示了如何使用默认的lambda参数:
from PyQt4 import QtGui
class Window(QtGui.QWidget):
def __init__(self):
QtGui.QWidget.__init__(self)
layout = QtGui.QVBoxLayout(self)
for index in range(4):
instance = QtGui.QCheckBox('Checkbox(%d)' % index, self)
instance.stateChanged.connect(
lambda state, instance=instance:
self.mySlot(instance.text()))
layout.addWidget(instance)
def mySlot(self, text):
print('clicked: %s' % text)
if __name__ == '__main__':
import sys
app = QtGui.QApplication(sys.argv)
window = Window()
window.show()
sys.exit(app.exec_())
答案 1 :(得分:1)
我遇到同样的问题,您应该使用functools.partial
,例如:
for key, val in a_DICT_THAT_YOU_STORED_YOUR_OBJECTS_AND_STRINGS:
obj = partial( findInstance.projectsInstance.myslot,arg1="TWCH",arg2=self,arg3=key,arg4=val.checkState() )
QtCore.QObject.connect(val, QtCore.SIGNAL(_fromUtf8("stateChanged (int)")), obj)
当然,argX应该设置你的函数名参数的真实名称。
答案 2 :(得分:0)
问题是你正在使用lambda
创建一个函数,其中函数内的一些变量不作为函数的参数传入。执行lambda函数时,当发出信号时,它会使用那个时刻的变量值(如instance
)。要清楚,您所做的每个lambda函数都是在运行时使用instance
的值,而不是定义时间。所以instance
只保存对我们循环的最后一次迭代中使用的对象的引用,这解释了你所看到的行为。
这里可以找到一些有用的信息(也可以阅读评论)http://eli.thegreenplace.net/2011/04/25/passing-extra-arguments-to-pyqt-slot/
从以上链接的评论:
你可以做的是有另一个函数生成lambda,即 类似的东西:
def make_callback(param): return lambda: self.on_button(param)
在连接中,请致电
make_callback(i)
。然后是一个不同的lambda 为每次迭代创建。
因此,您需要对此进行概括并将instance
之类的内容传递给make_callback
函数,然后将lambda
定义放在make_callback
函数中。我会提供一个明确的例子,但正如另一个答案所说,你的格式似乎在你的问题中变得非常混乱,我可能会因你的具体应用而弄错。如果你没有按照我的说法进行操作,那么让你的问题中的代码更清晰,我将会创建一个例子!