Tkinter循环生成菜单点击均触发最后项的问题及解决
解决Tkinter循环生成菜单触发最后一项逻辑的问题
你遇到的问题是Python中lambda的延迟绑定特性导致的。在循环里创建lambda时,它不会立即捕获当前循环的font_size值,而是等到lambda被调用(也就是点击菜单项)时,才去查找font_size变量的当前值——这时候循环已经执行完毕,font_size指向的是列表里最后一个元素,所以所有菜单项都会触发最后一项的逻辑。
方案1:给lambda添加默认参数绑定当前值
修改循环里的lambda,通过默认参数把当前的font_size值固定下来,每个lambda都会捕获到循环时的对应值:
for font_size in font_sizes : font_size_menu.add_command( label=font_size, command=lambda size=font_size: function(size) )
这里的核心是size=font_size:每次循环迭代时,Python会把当前的font_size值赋值给lambda的默认参数size,后续调用lambda时就会使用这个绑定好的固定值,而不是引用循环结束后的font_size变量。
方案2:使用functools.partial包装函数
用functools.partial创建预先绑定参数的函数对象,效果和上面一致:
先导入functools模块:
from functools import partial
再修改循环代码:
for font_size in font_sizes : font_size_menu.add_command( label=font_size, command=partial(function, font_size) )
partial会直接把当前的font_size值绑定到function的第一个参数上,生成新的可调用对象,每个菜单项的command都会对应各自的绑定值。
内容的提问来源于stack exchange,提问作者python.developer
相关产品推荐
相关产品推荐

