如何从多个Tkinter Entry框获取DoubleVar数据并实现.dat文件存读
问题:多参数Tkinter界面的存读功能实现
我是编程新手,想要实现让用户保存一组参数、后续无需修改代码即可复用的功能。编写了简化版Tkinter代码,但目前仅能处理单个Entry框的参数存读;添加第二个Entry框时,保存操作会将内容拼接而非分别存储。
原简化代码
import tkinter from tkinter import * from tkinter import filedialog from tkinter import ttk import sqlite3 import pickle root = Tk() root.title("Cabinet Cut List Calculator") frame = LabelFrame(root) frame.pack() toek = DoubleVar(value=3.5) default_hgt = IntVar(value=42) parms_list = [toek, default_hgt] def SaveParms(): parms_name = filedialog.asksaveasfilename(initialdir="/Users/Owner/Desktop/Python/cab databases/Parameters", title="Save Parameters", filetypes=(("Dat Files", "*.dat"),("All Files", "*.*"))) if parms_name: if not parms_name.endswith(".dat"): parms_name = f"{parms_name}.dat" parms_list = y.get() output_parms = open(parms_name, 'wb') pickle.dump(parms_list, output_parms) def LoadParms(): parms_name = filedialog.askopenfilename(initialdir="/Users/Owner/Desktop/Python/cab databases/Parameters", title="Load Parameters", filetypes=(("Dat Files", "*.dat"),("All Files", "*.*"))) if parms_name: y.delete(0, END) input_parm = open(parms_name, "rb") load_item = pickle.load(input_parm) for i in load_item: y.insert(END, i) def DelParms(): y.delete(0,END) the_menu = Menu(root) root.config(menu = the_menu) file_menu = Menu(the_menu, tearoff=False) the_menu.add_cascade(label="File", menu= file_menu) file_menu.add_command(label="Save Parameters", command= SaveParms) file_menu.add_command(label="Load Parameters", command= LoadParms) file_menu.add_separator() file_menu.add_command(label="Clear Parameters", command= DelParms) y = Entry(frame, textvariable=toek) y.pack(side=RIGHT) yl= Label(frame, text = "1....") yl.pack() frame2 = LabelFrame(root) frame2.pack() x = Entry(frame2, textvariable= default_hgt) x.pack(side=RIGHT) xl= Label(frame2, text = "2....") xl.pack() root.mainloop()
尝试的错误代码及报错
尝试用for循环处理parms_list:
for i in parms_list: parms_list =+ i.get()
出现报错:
parms_list =+ i.get() ^^^^^ AttributeError: 'str' object has no attribute 'get'
我对pickle模块不熟悉,后续修改SaveParms函数后得到的new_list仅为字符串,无法执行.get()方法获取变量值,希望得到解决方案。
解决方案
核心问题分析
- 错误地将
parms_list重新赋值为单个Entry的字符串内容,导致后续循环时parms_list变成字符串而非Tkinter变量列表,调用.get()时触发类型错误。 - 保存参数时需收集所有变量的当前值而非单个Entry内容;加载时需将每个值对应设置回原变量,而非仅插入到第一个Entry。
修改后的完整代码
import tkinter from tkinter import * from tkinter import filedialog import pickle root = Tk() root.title("Cabinet Cut List Calculator") frame = LabelFrame(root) frame.pack() # 定义参数变量 toek = DoubleVar(value=3.5) default_hgt = IntVar(value=42) parms_list = [toek, default_hgt] def SaveParms(): parms_name = filedialog.asksaveasfilename( initialdir="/Users/Owner/Desktop/Python/cab databases/Parameters", title="Save Parameters", filetypes=(("Dat Files", "*.dat"), ("All Files", "*.*")) ) if not parms_name: return # 用户取消保存,直接返回 # 自动添加.dat后缀 if not parms_name.endswith(".dat"): parms_name += ".dat" # 收集所有参数的当前值 saved_values = [var.get() for var in parms_list] # 用pickle保存列表,with语句自动管理文件关闭 with open(parms_name, 'wb') as output_parms: pickle.dump(saved_values, output_parms) def LoadParms(): parms_name = filedialog.askopenfilename( initialdir="/Users/Owner/Desktop/Python/cab databases/Parameters", title="Load Parameters", filetypes=(("Dat Files", "*.dat"), ("All Files", "*.*")) ) if not parms_name: return # 用户取消加载,直接返回 # 加载保存的参数值 with open(parms_name, "rb") as input_parm: load_item = pickle.load(input_parm) # 将每个值对应设置回变量(确保数量匹配) if len(load_item) == len(parms_list): for var, value in zip(parms_list, load_item): var.set(value) def DelParms(): # 清空所有Entry并重置为默认值 y.delete(0, END) x.delete(0, END) toek.set(3.5) default_hgt.set(42) # 菜单设置 the_menu = Menu(root) root.config(menu=the_menu) file_menu = Menu(the_menu, tearoff=False) the_menu.add_cascade(label="File", menu=file_menu) file_menu.add_command(label="Save Parameters", command=SaveParms) file_menu.add_command(label="Load Parameters", command=LoadParms) file_menu.add_separator() file_menu.add_command(label="Clear Parameters", command=DelParms) # 界面元素 y = Entry(frame, textvariable=toek) y.pack(side=RIGHT) yl = Label(frame, text="1....") yl.pack() frame2 = LabelFrame(root) frame2.pack() x = Entry(frame2, textvariable=default_hgt) x.pack(side=RIGHT) xl = Label(frame2, text="2....") xl.pack() root.mainloop()
关键修改点说明
SaveParms函数优化:
- 用列表推导式
[var.get() for var in parms_list]收集所有变量的当前数值,生成可被pickle保存的列表。 - 使用
with语句管理文件,自动处理关闭操作,避免资源泄漏。 - 增加用户取消保存的判断,防止后续代码报错。
- 用列表推导式
LoadParms函数优化:
- 加载后通过
zip将保存的值与原变量一一对应,调用var.set(value)将值同步到变量,所有Entry会自动更新内容。 - 增加长度匹配判断,避免因保存参数数量不匹配导致的错误。
- 加载后通过
DelParms函数优化:
- 同时清空两个Entry,并重置为默认值,提升用户体验。
变量作用域修复:
- 不再在函数内重新赋值
parms_list,直接使用全局定义的变量列表,彻底避免类型错误。
- 不再在函数内重新赋值
内容的提问来源于stack exchange,提问作者David Williams
相关产品推荐
相关产品推荐

