Tkinter循环创建按钮时所有按钮绑定命令一致该如何解决
问题根源
你遇到的是Python闭包的迟绑定特性导致的问题:lambda函数内部引用的循环变量t,不会在lambda创建时就捕获当前值,而是等到按钮被点击、lambda实际执行的时候才会去查找t的最终值。此时循环已经执行完毕,t固定为options数组的最后一个元素,所以所有按钮触发的命令参数都完全相同。
解决方案
有两种常用的修复方式:
方式1:给lambda添加默认参数(最简单无需导入)
默认参数会在函数定义阶段完成求值,刚好可以保存每轮迭代的t实例,修改command配置行即可:
btn.configure(bg='black', fg='white', borderwidth=0, font=font, command=lambda t=t: optionCommand(t.nextStageIndex, t.action))
原理:每轮迭代创建lambda时,会把当前的t作为默认值赋值给形参t,后续调用lambda时如果不传参数,就会使用创建时保存的这个默认值,不会再去查找外部的循环变量。
方式2:使用functools.partial绑定参数
如果不想用默认参数的写法,可以用标准库的partial方法提前绑定参数,创建时就把当前迭代的参数固定下来:
首先导入partial:
from functools import partial
然后修改command配置:
btn.configure(bg='black', fg='white', borderwidth=0, font=font, command=partial(optionCommand, t.nextStageIndex, t.action))
原理:partial会在创建时就把传入的参数和目标函数绑定,生成一个新的无参可调用对象,直接作为按钮的command使用即可,不存在迟绑定问题。
内容的提问来源于stack exchange,提问作者Kasper103
相关产品推荐
相关产品推荐

