2

画面に複数のボタンを自動的に入力しようとしています(forループを使用)

スニペットは次のとおりです。

    i = 0
    for w in [1,2,3,4,5,6,7,8]:
        by.append(wx.Button(panel,label=w,pos = wx.Point(50*i,0)))
        by[i].Bind(wx.EVT_LEFT_DOWN,lambda event: self.OnClicked(event,by[i]))
        i += 1
    i = 0

イベントが発生すると、 を設定したためi = 0、最後のボタンをクリックしても、すべてのイベントが最初のボタンにルーティングされます。for ループを使用せずにスロットを設定すると、機能することはわかっています。しかし、画面上に約 50 個のボタンを作成する必要があり、それを自動的に行いたいとしましょう。スロットの設定方法を教えてください。

4

1 に答える 1

2

問題はラムダ式lambda event: self.OnClicked(event,by[i]))です。ここで基本的な問題の詳細を読むことができます: (ラムダ) 関数クロージャは何をキャプチャしますか? .

しかし、要するに:iはラムダ式の作成に固定されていません。ループが終了した後、すべてのラムダ式はまだ を参照していiます。つまり、すべて同じ値です。

汚い修正は、代わりにこれを使用することです:

by[i].Bind(wx.EVT_LEFT_DOWN,lambda event, i=i: self.OnClicked(event,by[i]))

ただし、別のヘルパー関数を使用して変数バインディングを行う方がよい場合があります。

def addOnClicked(i,w):
    by.append(wx.Button(panel,label=w,pos = wx.Point(50*i,0)))
    by[i].Bind(wx.EVT_LEFT_DOWN,lambda event: self.OnClicked(event,by[i]))

for i in range(8):
    addOnClicked(i,i+1)
于 2012-08-18T14:04:37.583 に答える