2

ループ内に一連のバインディングを作成するための次のコードがあります。

from Tkinter import *
keys = {0:'m', 1:'n', 2:'o'}
def SomeFunc(event=None,number=11):
    print keys[number], number
root = Tk()
field = Canvas(root, height = 200, width = 200, bg = "gray") 
for i in range(2):
    root.bind("<KeyPress-%c>" % keys[i],lambda ev:SomeFunc(ev,i))
field.pack()
root.mainloop()

私の問題は、「m」または「n」を押すSomeFuncと、引数として変数「i」を使用して関数が呼び出されることです。「m」を押すと引数として0(「bind」を使用した場合は「i」の数値)、「n」を押すと1で呼び出されるようにしたいと思います。これはできますか?

4

1 に答える 1

5

ここでの問題は、変数iがによってキャプチャされるlambdaことですが、たとえば次のような小さなヘルパー関数を作成することで回避できます。

for i in range(2):
    def make_lambda(x):
        return lambda ev:SomeFunc(ev,x)
    root.bind("<KeyPress-%c>" % keys[i], make_lambda(i))

これにより、作成するバインディングごとに新しいスコープが作成されるため、ループの実行とforループ中の変更はi、すでにラムダ関数に影響を与えません。

于 2013-01-10T15:03:55.980 に答える