Tkinter Checkbutton循环绑定command始终传入最后元素问题咨询
这是Python中lambda表达式的延迟绑定特性导致的问题:
- 循环内定义的lambda不会在定义时立即捕获
site、var或btn的当前值,而是会在lambda被实际调用(也就是你点击复选框)时,才去查找这些变量的当前引用。 - 当循环结束后,
site、var、btn这三个变量都会指向循环最后一次迭代的对象(也就是最后一个站点"mgr"对应的组件和变量),所以无论点击哪个复选框,lambda都会取到最后一次迭代的值。
你尝试的两种传递方式都会失效:
- 使用
var.get()时,var在循环中被不断重新赋值,最终指向最后一个StringVar实例,所有lambda调用时都会获取这个实例的值; - 使用
btn['text']时,btn最终指向最后一个Checkbutton实例,所有lambda都会读取这个按钮的文本。
解决办法
要让lambda捕获当前循环迭代的变量值,可以通过以下两种方式:
方式1:给lambda添加默认参数
通过给lambda设置默认参数,强制在定义时捕获当前变量的快照:
for site in PcapLogic.deciphered_bin_df.columns: # 创建组件 self.btns.append(btn := ttk.Checkbutton(scrolled_text, text=site, style="Custom.TCheckbutton")) self.vars.append(var := tk.StringVar(btn, site, site)) # 用默认参数捕获当前的var或site btn.configure( variable=var, onvalue=site, offvalue="", # 捕获当前迭代的var command=lambda current_var=var: AppBoot.add_new_param_to_ini(current_var.get()) )
或者直接捕获site(因为onvalue已经设为site,也可以直接传递site):
btn.configure( variable=var, onvalue=site, offvalue="", command=lambda current_site=site: AppBoot.add_new_param_to_ini(current_site) )
方式2:使用functools.partial
functools.partial可以提前绑定函数参数,避免lambda的延迟绑定问题:
from functools import partial for site in PcapLogic.deciphered_bin_df.columns: # 创建组件 self.btns.append(btn := ttk.Checkbutton(scrolled_text, text=site, style="Custom.TCheckbutton")) self.vars.append(var := tk.StringVar(btn, site, site)) btn.configure( variable=var, onvalue=site, offvalue="", # 绑定当前site作为参数 command=partial(AppBoot.add_new_param_to_ini, site) )
内容的提问来源于stack exchange,提问作者Dorin
相关产品推荐
相关产品推荐

