0

これが私の問題です。n個のQLineEditウィジェットを作成したい( nは入力値に応じて任意の数にすることができます)。これらのQLineEditウィジェットを作成してオブジェクト名とテキストを指定することはできますが、それらすべてにシグナルを定義することはできません (すべてのQLineEditウィジェットが対話時にシグナルを発するようにしたい)。コードの例を次に示します。

self.fieldList = {}

for (i, value) in attrMap.iteritems():
    self.fieldList["valueField" + str(i)] = QtGui.QLineEdit()
    self.fieldList["valueField" + str(i)].setObjectName(_fromUtf8("attributeValueField_{0}".format(i)))
    self.fieldList["valueField" + str(i)].setText(_fromUtf8("{0}".format(value.toString())))
    self.fieldList["valueField" + str(i)].cursorPositionChanged.connect(lambda: (self.checkState(self.fieldList["valueField" + str(i)])))

問題は最後の行に残ります。

self.fieldList["valueField" + str(i)].cursorPositionChanged.connect(lambda: (self.checkState(self.fieldList["valueField" + str(i)])))

シグナルはすべてのウィジェットに固執すると思いましたが、ループのため、シグナルは最後のウィジェットに到達するまでウィジェットからウィジェットに「ジャンプ」するため、最後のウィジェットのみがシグナルを発信できます。では、変更されたときにすべてのウィジェットがシグナルを発するようにするにはどうすればよいでしょうか?

4

2 に答える 2

2

ここでの説明と一般的な解決策(他にもたくさんあります。たとえば、「python lambda loop parameter」を検索してください:https://stackoverflow.com/a/938493

別の一般的な解決策は、部分関数を使用することです。

import functools
slot = functools.partial( self.checkState, self.fieldList["valueField" + str(i)] )
self.fieldList["valueField" + str(i)].cursorPositionChanged.connect( slot )
于 2012-06-22T11:43:00.513 に答える
0

ここでの問題はクロージャーです。ラムダでは、定義されたときではなく、ラムダ関数が呼び出されたときiの値を参照します。iしたがって、ループが終了すると、すべてiの s が同じ値になります。

これを修正するには:

self.fieldList = {}

for (i, value) in attrMap.iteritems():
    self.fieldList["valueField" + str(i)] = QtGui.QLineEdit()
    self.fieldList["valueField" + str(i)].setObjectName(_fromUtf8("attributeValueField_{0}".format(i)))
    self.fieldList["valueField" + str(i)].setText(_fromUtf8("{0}".format(value.toString())))
    self.fieldList["valueField" + str(i)].cursorPositionChanged.connect(lambda old, new, i=i: (self.checkState(self.fieldList["valueField" + str(i)])))

この問題の詳細については、こちらをご覧ください

于 2012-06-22T11:45:18.367 に答える