Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/joomla/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 在PyQt中将列表元素作为信号/插槽参数传递_Python_Pyqt_Arguments_Signals Slots - Fatal编程技术网

Python 在PyQt中将列表元素作为信号/插槽参数传递

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

我想把调用信号的对象作为参数传递给函数,这样我就可以在函数中使用该对象进行操作。该对象是QLineEdit小部件。以下是一个例子:

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
定义为旧变量,将right
i
定义为新变量。。。尝试用谷歌搜索,但没有成功

好吧,我假设你问题中的代码是一个示例,而不是你真正的代码。因为,由于在循环中创建小部件时没有附加参数,因此结果将是窗口中所有对象的重叠。您可以看到,所有线条编辑都将位于同一位置(默认情况下,窗口的左上部分)。如果是这样的话,就很难说问题出在哪里,因为在我看来,这只是知道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!")
如您所见,映射器将只发送索引作为参数。因此,我想您需要使用附加的args
palete1、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