Python 在PyQt中将列表元素作为信号/插槽参数传递
我想把调用信号的对象作为参数传递给函数,这样我就可以在函数中使用该对象进行操作。该对象是QLineEdit小部件。以下是一个例子:Python 在PyQt中将列表元素作为信号/插槽参数传递,python,pyqt,arguments,signals-slots,Python,Pyqt,Arguments,Signals Slots,我想把调用信号的对象作为参数传递给函数,这样我就可以在函数中使用该对象进行操作。该对象是QLineEdit小部件。以下是一个例子: self.fieldList = [] for i in range(10): self.valueField = QtGui.QLineEdit() self.fieldList.append(self.valueField) self.fieldList[i].cursorPositionChanged.conn
self.fieldList = []
for i in range(10):
self.valueField = QtGui.QLineEdit()
self.fieldList.append(self.valueField)
self.fieldList[i].cursorPositionChanged.connect(lambda: (self.checkState(self.fieldList[i], palette1, palette2)))
def checkState(self, line, palette1, palette2):
if len(line.text()) > 3:
line.setPalette(palette1)
else:
line.setPalette(palette2)
所以,正如您所看到的,我试图在checkState()函数中将list元素self.fieldList[I]作为名为line的参数传递。如果我在checkState()函数中显式定义fieldList元素(即self.fieldList[0]),则代码工作正常,但我无法将其作为参数传递。我做错了什么
顺便说一句,当我尝试运行程序时,编译器并没有给我错误消息,但它根本无法完成它应该完成的工作(当我写入超过3个字符时,更改QLineEdit的颜色)
编辑:
@dex19dt
是的,这是一个例子,但你是对的!只有最后一个QLineEdit可以正常工作
问题是,我不能给出所有这些小部件的名称,因为它们的数量取决于所选的层,这意味着有时有5个小部件,有时甚至有11个或75个
我可以很容易地命名这些小部件并设置如下文本:
self.fieldList[i].setObjectName(_fromUtf8("attributeValueField_{0}".format(i)))
self.fieldList[i].setText(_fromUtf8("{0}".format(value.toString())))
这对每个小部件都很好,但我不知道如何定义信号?你有什么想法吗
编辑: @dex19dt 好的,我问了索引不“粘住”函数调用的问题,我发现这正是python的工作方式,为了解决这个问题,我需要替换这一行:
self.fieldList[i].cursorPositionChanged.connect(lambda: (self.checkState(self.fieldList[i], palette1, palette2)))
关于这一点:
self.fieldList[i].cursorPositionChanged.connect(lambda old, new, i=i: (self.checkState(self.fieldList[i], palette1, palette2)))
这样,当前索引复制到信号索引。虽然我不太清楚为什么会有新的、旧的零件。它是指lambda函数还是简单地将left
i
定义为旧变量,将righti
定义为新变量。。。尝试用谷歌搜索,但没有成功 好吧,我假设你问题中的代码是一个示例,而不是你真正的代码。因为,由于在循环中创建小部件时没有附加参数,因此结果将是窗口中所有对象的重叠。您可以看到,所有线条编辑都将位于同一位置(默认情况下,窗口的左上部分)。如果是这样的话,就很难说问题出在哪里,因为在我看来,这只是知道lineEdit的哪个实例正在发送信号的问题
因此,我将告诉您如何使上述代码工作,如果不是这样,您可以随时回复
这都与信号的连接方式有关。如果查看代码,您将使用相同的名称(self.valueField)创建所有线条编辑。这些对象都是创建的,它们在内存中有自己的位置,但它们在连接中的引用总是被最后一个连接覆盖。你甚至可以做这个测试。如果将此行添加到checkState函数:
print self.fieldList.index(行)
您将看到,始终为列表的最后一项调用信号,这也是最后连接的信号
只需使用不同的名称逐个设置所有线条编辑。创建你的列表,同时输入其中的所有名字。这样,for循环将只连接线条编辑,而不再创建它们
编辑:
嗯。实现这一点的一种方法是使用信号映射器。
请看下面的图片
在上面的示例中,您可以执行以下操作:
首先声明映射器,与声明其他小部件的方式相同:
self.myMapper = QtCore.QSignalMapper()
在你的第一个for循环之后。您可以迭代列表:
for item in self.fieldList:
self.myMapper.setMapping(item, self.fieldList.index(item))
item.textEdited.connect(self.myMapper.map)
self.myMapper.mapped[int].connect(checkState)
所以这将要做的是,它将映射列表中的每个对象及其对应的列表索引(int)。
因此,当发出一个信号时,映射器调用checkState函数,并将该索引值作为参数。这样,您可以再次使用列表到达您的对象:
def checkState(i):
print (self.fieldList[i].objectName())
self.fieldList[i].setText("It works!")
如您所见,映射器将只发送索引作为参数。因此,我想您需要使用附加的argspalete1、palete2来调整函数。
或者,您可以使用一个类似于筛选器的初始函数,然后调用其中的右checkState函数:
def myfilter(i):
checkState(self.fieldList[i], palette1, palette2)
我很确定还有其他方法可以实现这一点,但这一种方法可以实现这一点,但没有更好的解决方案。好吧,我假设您问题中的代码是一个示例,而不是您真正的代码。因为,由于在循环中创建小部件时没有附加参数,因此结果将是窗口中所有对象的重叠。您可以看到,所有线条编辑都将位于同一位置(默认情况下,窗口的左上部分)。如果是这样的话,就很难说问题出在哪里,因为在我看来,这只是知道lineEdit的哪个实例正在发送信号的问题
因此,我将告诉您如何使上述代码工作,如果不是这样,您可以随时回复
这都与信号的连接方式有关。如果查看代码,您将使用相同的名称(self.valueField)创建所有线条编辑。这些对象都是创建的,它们在内存中有自己的位置,但它们在连接中的引用总是被最后一个连接覆盖。你甚至可以做这个测试。如果将此行添加到checkState函数:
print self.fieldList.index(行)
您将看到,始终为列表的最后一项调用信号,这也是最后连接的信号
只需使用不同的名称逐个设置所有线条编辑。创建你的列表,同时输入其中的所有名字。这样,for循环将只连接线条编辑,而不再创建它们
编辑:
嗯。实现这一点的一种方法是使用信号映射器。
请看下面的图片
在上面的示例中,您可以执行以下操作:
首先声明映射器,与声明其他小部件的方式相同:
self.myMapper = QtCore.QSignalMapper()
在你的第一个for循环之后。您可以迭代列表:
for item in self.fieldList:
self.myMapper.setMapping(item, self.fieldList.index(item))
item.textEdited.connect(self.myMapper.map)
self.myMapper.mapped[int].connect(checkState)
因此,这将做的是t