解决方案思路来自 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有异曲同工之妙,感兴趣的同学可以了解一下