我有一个循环。我创建了一个
QCheckBox
并将其放入 QTableWidget
单元格中,一切正常。在循环的每一步中,我都为 myslot SLOT 调用了一个 connect
函数,但仅应用了最后一个 QCheckBox
实例。我用谷歌搜索了很多,发现很多人都有我的问题。我已经应用了他们的解决方案,但我的问题仍然存在。
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
?
将循环变量放入默认参数中,如下所示:
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_())
我有同样的问题,你应该使用
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 应该设置为你的函数名称的参数的真实名称。
问题是您正在使用
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)
并在连接中拨打
。那么不同的 lambda 是 为每次迭代创建。make_callback(i)
因此,您需要概括这一点,并将
instance
等内容传递给 make_callback
函数,然后将 lambda
定义放在 make_callback
函数中。我会提供一个清晰的例子,但正如另一个答案所说,您的问题中的格式似乎变得非常混乱,我可能会为您的特定应用程序弄错。如果您没有遵循我所说的,请使问题中的代码更清晰,我将尝试创建一个示例!
创建单独的函数“make_callback”并在 for 循环中向其传递参数的示例。这解决了只有最后一个 lambda 函数连接到实例的问题。
for button_widget, button_dict in zip(self.button_widget_dictionary.values(),
self.button_page_dictionary.values()):
button_widget.pressed.connect(self.make_callback(button_dict))
def make_callback(self,button_dict):
return lambda: self.central_widget.add_graph_tab_dict(
button_dict['Tab_options']['name'][0] + ': '
+ button_dict['Tab_options']["graph_title"][0:4] + "...",
button_dict)