tkinter command传参问题解决


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


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM