Python Tkinter循环生成Checkbutton子控件取值报PY_VAR不存在错误问题
问题原因
- 循环中创建
Checkbutton绑定的BooleanVar()是临时变量,循环迭代结束后没有任何引用指向这些变量,会被Python垃圾回收机制自动销毁,对应的底层Tcl变量也同步被释放,因此调用getvar读取时会抛出找不到变量的错误。 - 提前勾选复选框时,勾选操作会在Tcl runtime层临时重建对应变量,因此不会报错,但由于Python侧已经丢失了变量的绑定关联,读取结果为空。
- 现有代码未将复选框的取值结果添加到结果列表中,即使变量正常也拿不到复选框状态。
解决方法
修改逻辑如下:
- 新增实例属性存储所有复选框绑定的
BooleanVar,避免变量被垃圾回收 - 读取复选框状态时直接调用对应
BooleanVar的get()方法即可 - 推荐按行匹配控件取值,避免通过
winfo_children取值时受控件创建顺序影响出现错位
修正后完整代码:
from tkinter import * class App(): def __init__(self): self.ws = Tk() self.frame = LabelFrame(self.ws) self.frame.grid(row=1,column=1) # 新增列表存储所有复选框的BooleanVar,避免被回收 self.check_vars = [] for i in range(16): e = Label(self.frame, text=str(i + 1) + '.') e.grid(row=i+1, column=1) e1 = Entry(self.frame, width=8) e1.grid(row=i+1, column=2) e2 = Entry(self.frame) e2.grid(row=i+1, column=3) # 先创建变量存入实例列表,再绑定到Checkbutton var = BooleanVar() self.check_vars.append(var) check = Checkbutton(self.frame, variable=var, onvalue=True, offvalue=False) check.grid(row=i+1, column=4, sticky=E) but = Button(self.ws,text='Get ALL',command=self.getall) but.grid(row=17,column=1) self.ws.mainloop() def getall(self): res_list = [] # 按行整理结果,取值逻辑更清晰不易错位 for i in range(16): row = i + 1 entry1 = self.frame.grid_slaves(row=row, column=2)[0] entry2 = self.frame.grid_slaves(row=row, column=3)[0] check_val = self.check_vars[i].get() res_list.append({ "行号": i+1, "输入框1": entry1.get(), "输入框2": entry2.get(), "复选框状态": check_val }) print('结果列表:',res_list) if __name__ == '__main__': App()
内容的提问来源于stack exchange,提问作者320V
相关产品推荐
相关产品推荐

