循环中的 QtCore.QObject.connect 仅影响最后一个实例
- 2025-04-15 09:20:00
- admin 原创
- 31
问题描述:
我遇到了一个循环。我创建了一个循环QCheckBox
并将其放入一个QTableWidget
单元格中,一切正常。在循环的每一步中,我都调用了一个connect
函数,for myslot SLOT,但只有最后一个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
?
解决方案 1:
将循环变量放在默认参数中,如下所示:
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_())
解决方案 2:
我有同样的问题,你应该使用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 应该设置为你的函数名的参数的真实名称。
解决方案 3:
问题在于,你创建的函数使用了 ,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
函数内部。我会提供一个清晰的例子,但正如另一个答案所说,你的问题中的格式似乎非常混乱,我很可能无法理解你具体应用的格式。如果你不明白我的意思,请将问题中的代码写得更清晰一些,我会尝试创建一个示例!
解决方案 4:
创建单独的函数“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)
扫码咨询,免费领取项目管理大礼包!