C++ 循环中的QtCore.QObject.connect仅影响最后一个实例
我有一个线圈。我创建了一个C++ 循环中的QtCore.QObject.connect仅影响最后一个实例,c++,qt,pyqt,qtcore,qt-signals,C++,Qt,Pyqt,Qtcore,Qt Signals,我有一个线圈。我创建了一个QCheckBox并将其放入QTableWidget单元格中,一切正常。在循环的每个步骤中,我都为myslot SLOT调用了一个connect函数,但只应用了最后一个QCheckBox实例。我在谷歌上搜索了很多,发现很多人都有我的问题。我已经应用了他们的解决方案,但我的问题仍然存在 for row in xrange(len(uniqueFields)): instance = QtGui.QCheckBox(uniqueFields[row], findIn
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)
注意:myconnect
函数返回True
如何在枚举所有
实例的循环中创建connect
函数?问题在于,您正在使用lambda
创建函数,函数中的一些变量没有作为参数传递给函数。当执行lambda函数时,当发出信号时,它使用这些变量的值(如实例
)。需要明确的是,您创建的每个lambda函数在运行时都使用instance
的值,而不是定义时间。因此,instance
只包含对循环最后一次迭代中使用的对象的引用,这解释了您看到的行为
可以在这里找到一些有用的信息(也请阅读评论)
从上述链接的评论中:
你可以做的是让另一个函数生成lambda,即。
比如:
def make_callback(param):
return lambda: self.on_button(param)
在连接中,调用make\u callback(i)
。然后是另一个lambda
为每个迭代创建
因此,您需要对其进行推广,并将实例
之类的内容传递给make_callback
函数,然后将lambda
定义放在make_callback
函数中。我会提供一个明确的例子,但正如另一个答案所说,您的格式在您的问题中似乎变得非常混乱,我可能会在您的特定应用程序中出错。如果你没有按照我说的去做,请把问题中的代码弄清楚,我会尝试创建一个例子 问题在于,您正在使用lambda
创建一个函数,其中函数中的一些变量没有作为参数传递给函数。当执行lambda函数时,当发出信号时,它使用这些变量的值(如实例
)。需要明确的是,您创建的每个lambda函数在运行时都使用instance
的值,而不是定义时间。因此,instance
只包含对循环最后一次迭代中使用的对象的引用,这解释了您看到的行为
可以在这里找到一些有用的信息(也请阅读评论)
从上述链接的评论中:
你可以做的是让另一个函数生成lambda,即。
比如:
def make_callback(param):
return lambda: self.on_button(param)
在连接中,调用make\u callback(i)
。然后是另一个lambda
为每个迭代创建
因此,您需要对其进行推广,并将实例
之类的内容传递给make_callback
函数,然后将lambda
定义放在make_callback
函数中。我会提供一个明确的例子,但正如另一个答案所说,您的格式在您的问题中似乎变得非常混乱,我可能会在您的特定应用程序中出错。如果你没有按照我说的去做,请把问题中的代码弄清楚,我会尝试创建一个例子 将循环变量放入默认参数中,如下所示:
lambda state, instance=instance: findInstance.projectsInstance.myslot(
"TWCH", findInstance, instance.text(), instance.checkState(), instance)
这将为每个lambda
提供其自身的实例
变量的本地副本
编辑
下面是一个演示如何使用默认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_())
将循环变量放入默认参数中,如下所示:
lambda state, instance=instance: findInstance.projectsInstance.myslot(
"TWCH", findInstance, instance.text(), instance.checkState(), instance)
这将为每个lambda
提供其自身的实例
变量的本地副本
编辑
下面是一个演示如何使用默认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应该设置为函数名参数的实名。我也有同样的问题,你应该使用functools。部分例如:
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@three_pineapples. 它工作得非常好:请参阅我的更新答案以了解一个工作示例。正如我在最初的回答中所解释的,默认参数用于缓存循环变量,因此不需要使用闭包(尽管也可以)。啊,抱歉,我跳过了instance=instance
部分(我刚刚读了instance
)。你的方法比我的建议干净得多,我将在我自己的代码中开始使用它,但它不起作用,因为在发出信号时没有参数传递到插槽。您需要创建一个没有参数的lambda,但它仍然有自己的实例副本。因此,我的答案是,使用函数lambda@three_pineapples. 它工作得非常好:请参阅我的更新答案以了解一个工作示例。正如我在最初的回答中所解释的,默认参数用于缓存循环变量,因此不需要使用闭包(尽管也可以)。啊,抱歉,我跳过了instance=instance
部分(我刚刚读了instance
)。你的方法比我的建议干净得多,我将开始在我自己的代码中使用它