2

次のコードに関する私の問題は、作成された各ボックスの個別の機能を持たせるために、ラムダを介してコールバックに 'i' (数字の単純な範囲ですが、number_boxes に従って変化します) を渡すことです。

チュートリアルを読んで、自分のコードでさまざまなことを試みましたが、うまくいかないか、「lambda() には引数が 2 つしか必要ありません」などのエラーが表示されます。「i」をリストにする必要があると思いますが、私はまだこの特定のエラーが発生します..

問題が発生するコードについてコメントしました。各ボックス内の値を返すだけでなく、テキストを上書きする必要があります。

ありがとうございました。

self.clicked = [] # In my __init__ definition
self.numbers = [StringVar() for i in xrange(self.number_boxes) ]   # Create Stringvar for each box

for i in xrange(self.number_boxes): # For each number, create a box

        self.clicked.append(False) # Not clicked in yet
        self.box.append(Entry(self.frame_table,bg='white',borderwidth=0, width=10, justify="center", textvariable=self.numbers[i], fg='grey')) # Textvariable where I enter a value to get after, need to do for each box (use box[i] but cannot for append)
        self.box[i].grid(row=row_list,column=column+i, sticky='nsew', padx=1, pady=1) 
        self.box[i].insert(0, "Value %g" % float(i+1))
        self.box[i].bind("<Button-1>", lambda event, index=i : self.callback(event, index)) # Need to pass the 'i's' to callback but having lambda difficulties

for i in self.numbers: 
        i.trace('w',lambda index=i: self.numberwritten(index) ) # Need for each box again here

def numberwritten(self, index): # A way of combining numberwritten and callback?
    po = self.box[index].get() # Get the values in each box
    print po

def callback(self, event, index):
        if (self.clicked[index] == False): # When clicked in box, overwrite default text with value and change colour to black, not grey
            self.box[index].delete(0, END)
            self.box[index].config(fg='black')
                self.clicked[index] = True

更新: 現在の問題: 'i' のすべての値をコールバックに渡す必要がありますが、1 つだけではなく、リストをラムダに入れる方法はありますか?

エラー:

Exception in Tkinter callback
Traceback (most recent call last):
File "C:\Python26\lib\lib-tk\Tkinter.py", line 1410, in __call__
return self.func(*args)
TypeError: lambda() takes at most 1 argument (3 given)
4

2 に答える 2

2

あなたのコードは非常に近いですが、この行は次のとおりです。

self.box[i].bind("<Button-1>", lambda self, event,i : self.callback(event, data))

する必要があります

self.box[i].bind("<Button-1>", lambda event, index=i: self.callback(event, index))

オブジェクトindexは、 の値を割り当てる任意のラベルですii変数名ではなくを渡すと、Python はエラーをスローすることに注意してください。そして、渡す必要はありませんself。関数呼び出しで使用することにより、暗黙的に渡されます: self.callback()

私の他の唯一のコメントはclicked、ユーザーが選択したオブジェクトを追跡できるように、リストに変換する必要があるということです。これを形成するのとまったく同じ方法boxで形成できます。幸運を。


clickedこれはあなたが抱えている現在の問題だと思うので、リストに変換するためのヒントをいくつか紹介します。編集: JF Sebastian のコメントごとに数行を変更しました。

# Create an empty list based on the number of boxes created 
# above. This could go in your class's __init__ function, 
# or it could be declared globally, depending on the scope
# of self.box and the loop which determines its length.
self.clicked = ([False] * len(self.box))

# Finally, in your callback, check one member of the list,
# depending on which box was clicked.
def cb(self, event, index):
    if not self.clicked[index]:
        self.box[index].delete(0, END)
        self.box[index].config(fg='black')
        self.clicked[index] = True
    # Print the value of each of the widgets stored in the box list.
    for i, j in enumerate(self.box):
        print("%ith element: %s" % (i, j.get()))  
于 2012-07-06T01:06:05.830 に答える
0

更新:あなたのラムダは完全に不必要なようです。それを完全に削除します。

試す:

self.box[i].bind("<Button-1>",self.callback)

それ以外の:

lambda self, event, i: self.callback(event, i)

アップデート:

私が答えを入力している間、あなたは状況を悪化させたように見えました.ラムダイディオムを少し明確にすることで、上記の私の解決策よりも役立つかもしれません. ;-)

ラムダ関数は、名前を持つ必要がないため、無名関数とも呼ばれます。

次の例を比較してください。

>>>ulist = 'a1 s3 d2 f4 k6 w9'.split()

def normal_sort(L,R):
    result = int(L[1]) - int(R[1])
    return result

>>> sorted(ulist, normal_sort)
['a1', 'd2', 's3', 'f4', 'k6', 'w9']

ラムダ関数と同じ:

sorted(ulist, lambda L, R: int(L[1])-int(R[1]))
['a1', 'd2', 's3', 'f4', 'k6', 'w9']

ラムダ関数には

  1. ノーネーム
  2. 引数なし括弧
  3. その単一のステートメントの評価が戻り値として返されるため、return ステートメントはありません。

ラムダ関数に名前を割り当てることで名前を付けることができます:

lambda_sort = lambda L, R: int(L[1])-int(R[1])

しかし、通常の機能に切り替えることはすでに有用かもしれません。

于 2012-07-05T14:19:52.913 に答える