2016-12-06 25 views
0

これはtkinterにあります。最後の行は、x = len(FRAME_LIST) "Buttons"をドロップダウンメニューに追加します。問題は、それらがすべて同じフレーム(FRAME_LISTの最後)を参照していることです。すべてのボタンがFRAME_LISTからの異なるフレームを参照するようにするにはどうすればいいですか?forループを使用してボタンを作成する方法

for F in FRAME_LIST: 
     frame = ChallengePage(mainframe,self, F) 
     self.frames[F] = frame 
     frame.grid(row = 0, column = 0, sticky = "nsew") 
     subMenu1.add_command(label = F.id, command = lambda: self.show_frames(F)) 

EDIT: 私はこの問題に遭遇したときので、より正確に言えば、私は大丈夫、問題は、私はローカル変数を宣言する必要があるので、私はこれを試してみましたと思った:

 A = F 
     subMenu1.add_command(label = F.id, command = lambda: self.show_frames(A)) 

しかし、 Aがループの内側に宣言され、すべてのループに再宣言されても、それは動作しませんでしたが、それでも同じ結果が得られます。

私はリンクを介して、今来た:https://docs.python.org/3/faq/programming.html#why-do-lambdas-defined-in-a-loop-with-different-values-all-return-the-same-result

それが解決策を示しています。

 subMenu1.add_command(label = F.id, command = lambda A = F: self.show_frames(A)) 

何とか魔法のように動作しますが、それは私の地元のAから任意の切り抜いている理由私は得ることはありません

答えて

0

これは、ループ内でlambdaを使用する場合の一般的な問題です。私は通常の代わりにpartialを使用します。

from functools import partial 

for F in FRAME_LIST: 
    frame = ChallengePage(mainframe, self, F) 
    self.frames[F] = frame 
    frame.grid(row=0, column=0, sticky="nsew") 
    subMenu1.add_command(label=F.id, command=partial(self.show_frames, F)) 

ので:closures

要約すると:あなたのループ内lambda名前の変数(F)のではなく、それは、ループの各反復の指す値を覚えています。ボタンをクリックしてコマンドをトリガーするまでには、Fという名前は、forループの繰り返しの最後の値を指しています。それがあなたのラムダに渡されます。一方、Partialsは、それぞれの反復でFが指すオブジェクトを認識し、それを追跡して、self.show_frames()が適切な引数で呼び出されるようにします。

関連する問題