簡體   English   中英

Python Tkinter按鈕回調

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM