解決方案思路來自 https://stackoverflow.com/questions/6920302/how-to-pass-arguments-to-a-button-command-in-tkinter
其實使用的都是封裝的方法,只是有不同的實現。
方案一:lambda函數
個人比較喜歡這個方法
ttk.Button(frame, text='button',command=lambda:func(param))
值得注意的是,這里存在一個小細節,不了解lambda函數機制的同學要注意一下,否則可能產生與你預期不符的結果。lambda函數只會在調用時執行內部語句,也就是說,如果你傳遞的參數(這里是param)是一個變量,並且在之后這個變量的值發生了變化,調用時就會傳入之后的值而不是你之前想要傳入的值。
舉個例子:
def print_add_one(a):
"""這個函數對參數加一並打印"""
print(a+1)
a = 1
button = ttk.Button(frame, text="press",command=lambda:print_add_one(a))
a = 5
# 點擊這個按鈕輸出會是 6
如果你正好有動態傳值的需要,那么這個恰能符合你的需求。如果你想要傳入固定的參數值,則我們需要用到默認參數解決這一問題。
示例如下:
lambda p=param:func(p)
這樣就能把參數固定下來了。
方案二:類封裝
import tkinter as tk
class Callback:
def __init__(self, func, *args, **kwargs):
self.func = func
self.args = args
self.kwargs = kwargs
def __call__(self):
self.func(*self.args, **self.kwargs)
def default_callback(t):
print("Button '{}' pressed.".format(t))
root = tk.Tk()
buttons = ["A", "B", "C"]
for i, b in enumerate(buttons):
tk.Button(root, text=b, command=Callback(default_callback, b)).grid(row=i, column=0)
tk.mainloop()
這里不多做介紹了,調用的地方像這樣實例化一個對象就行了。
方案三:functools的partial
from functools import partial
button = Tk.Button(master=frame, text='press', command=partial(func, arg))
partial用於創建一個類似原函數但有固定參數的偏函數,原型如下:
functools.partial(func, *args, **keywords)
和方案二玩法差不多,具體不多介紹了。
Note:
有趣的是,python類綁定方法的實現與partial有異曲同工之妙,感興趣的同學可以了解一下
