Tkinter动态按钮文本获取异常:点击按钮始终返回最后一个元素
解决Tkinter循环创建按钮时Command始终触发最后一个元素的问题
问题原因
Python的lambda表达式在定义时不会立即捕获循环变量的当前值,而是在调用lambda时才去查找变量的当前引用。当循环结束后,变量m或btn都会指向循环最后一次迭代的对象,因此无论点击哪个按钮,最终都会使用最后一个元素的值。
解决方案
有两种常用方法可以避免这个延迟绑定问题:
方法1:利用lambda默认参数捕获当前值
在lambda中添加默认参数,将当前循环的m值直接绑定到参数上,这样每次循环都会固定住当前的m值:
for m in msgs: btn = tk.Button(frame, text=m, command=lambda msg=m: choose_msg(msg)) btn.pack(side=tk.TOP)
方法2:使用functools.partial绑定参数
通过functools.partial将函数和当前的参数预先绑定,确保每个按钮的command对应正确的参数:
from functools import partial import tkinter as tk root = tk.Tk() root.geometry('200x200') frame = tk.Frame(root) frame.pack(side = tk.TOP) msgs = ['hello', 'goodbye', 'i dont know why', 'you say'] chosen = [] def choose_msg(msg): chosen.append(msg) print('test chosen: ', msg) for m in msgs: btn = tk.Button(frame, text=m, command=partial(choose_msg, m)) btn.pack(side=tk.TOP) root.mainloop()
完整修正代码(方法1示例)
import tkinter as tk root = tk.Tk() root.geometry('200x200') frame = tk.Frame(root) frame.pack(side = tk.TOP) msgs = ['hello', 'goodbye', 'i dont know why', 'you say'] chosen = [] def choose_msg(msg): chosen.append(msg) print('test chosen: ', msg) for m in msgs: btn = tk.Button(frame, text=m, command=lambda msg=m: choose_msg(msg)) btn.pack(side=tk.TOP) root.mainloop()
内容的提问来源于stack exchange,提问作者Guerre
相关产品推荐
相关产品推荐

