tkinter 38个网格按钮如何传递自身text属性至点击回调函数
核心问题澄清
首先tkinter没有内置类似thisItem的语法,无法直接在参数里写这种引用当前控件的写法。你原代码的写法存在两个本质错误:
- 写在
command参数里的带括号的函数调用(如collect_num(xxx)),会在按钮创建的瞬间就执行,完全等不到用户点击按钮的时机 - 代码里从未定义过
thisItem变量,运行时会直接抛出未定义变量的报错
可行实现方案
方案1:用lambda延迟执行,绑定按钮自身引用
这是最常用的实现方式,通过给lambda设置默认参数,把当前创建的按钮实例绑定到参数上,还能避免批量生成按钮时常见的闭包值陷阱(所有按钮都传最后一个值的问题):
def collect_num(num): print(num) # 单独创建单个按钮的写法 num0 = tk.Button(buttons, text="0", padx=10, pady=5, fg="white", bg="green") # 绑定command,取当前按钮的text属性作为参数传入 num0["command"] = lambda btn=num0: collect_num(btn["text"])
如果要批量生成0到38共39个按钮,这套写法可以直接复用,不需要逐个硬编码:
for num in range(39): btn = tk.Button(buttons, text=str(num), padx=10, pady=5, fg="white", bg="green") btn["command"] = lambda b=btn: collect_num(b["text"]) # 按网格位置摆放按钮 btn.grid(row=num // 10, column=num % 10)
方案2:通过事件对象直接获取触发控件
如果用bind绑定鼠标点击事件,事件回调函数会自动传入事件对象,这个对象的widget属性就是当前被点击的按钮实例,不需要提前手动绑定按钮引用:
num0 = tk.Button(buttons, text="0", padx=10, pady=5, fg="white", bg="green") num0.bind("<Button-1>", lambda e: collect_num(e.widget["text"]))
这套逻辑可以复用给所有按钮,不需要逐个写按钮的引用。
补充说明
- tkinter控件获取自身text属性有两种等价写法:
btn["text"]、btn.cget("text"),都可以正确拿到按钮显示的文本值 - 所有需要给按钮command传自定义参数的场景,都要靠lambda、
functools.partial这类方式把执行逻辑延迟到点击触发时,直接写函数调用的写法永远会在控件创建阶段就执行
内容的提问来源于stack exchange,提问作者Nikolay
相关产品推荐
相关产品推荐

