[英]Python Tkinter button callback
當我單擊由for循環創建的每個按鈕時,我正在嘗試打印出按鈕編號。 以下是我的嘗試。
import Tkinter as tk
root=tk.Tk()
def myfunction(a):
print a
for i in range(10):
tk.Button(root,text='button'+str(i),command=lambda:myfunction(i)).place(x=10,y=(10+(25*i)))
root.mainloop()
但不是打印出每個按鈕編號,而是每次都給我最后一個按鈕編號。 有什么我可以這樣做,當我點擊按鈕1,它將打印1,2為2,依此類推?
簡單的解決方法是每次創建lambda函數時使用當前值i初始化lambda函數。 這可以使用另一個虛擬變量j的Python默認值來完成。
command = lambda j=i: myfunction(j)
Blender的答案是一個聰明的解決方案,但如果你被函數抽象拋棄,這是另一種可行的方法。 它實際上只是創建一個保存在buttons
的映射,從Button
小部件到正確的數字。
import Tkinter as tk
root = tk.Tk()
def myfunction(event):
print buttons[event.widget]
buttons = {}
for i in range(10):
b = tk.Button(root, text='button' + str(i))
buttons[b] = i # save button, index as key-value pair
b.bind("<Button-1>", myfunction)
b.place(x=10,y=(10+(25*i)))
root.mainloop()
這是因為i
在你的匿名函數中引用的是計數器變量,而不是值:
from __future__ import print_function
x = [lambda: print(i) for i in range(10)]
for f in x:
f()
這產生了連續9
秒的輸出。
要解決這個問題,你必須使用兩個lambda
和shadow i
和第二個函數(它創建你的第一個函數):
from __future__ import print_function
x = [(lambda i: (lambda: print(i)))(i) for i in range(10)]
for f in x:
f()
雖然在那時,你最好只做一個命名函數:
def my_command(i):
def inner_function():
return my_function(i)
return inner_function
並使用它像這樣:
tk.Button(root, text='button' + str(i), command=my_command(i))
問題是tk中的Button命令忽略了任何參數,所以像mycommand(data)這樣的東西會被忽略。
我使用了很多按鈕,並決定將tk Button子類化為包含數據。 我稱之為DataButton並添加了一個數據成員(在本例中是一個索引號)。 這樣點擊時會傳回數據。 (索引號)現在我每次都希望它使用DataButton來保存索引甚至消息之類的信息。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.