Python Gym Tracker程序无法保存Excel,仅存首行且未读取输入控件求助
问题分析与修复方案
核心问题
- 输入控件与取值对象不匹配:你界面上用的是
Combobox(月份、用户)和Text(身高、体重等),但代码里却从从未显示在界面上的Entry控件取值,自然拿不到用户输入。 - 控件引用丢失:创建控件时用了链式调用(比如
cb1 = Combobox(...).place(...)),place()方法返回None,导致后续无法通过变量引用控件。 - 保存逻辑混乱:每次保存都新建Workbook覆盖原有数据,后续合并
track.xlsx和trackn.xlsx的操作不仅冗余,还会在trackn.xlsx不存在时报错。
修复步骤
- 修正控件创建方式:将控件创建与布局(
place())分开,保留控件的有效引用。 - 修正取值对象:从实际显示的
Combobox和Text控件获取输入值(注意Text控件取值要用get("1.0", tk.END).strip())。 - 优化保存逻辑:用Pandas直接读取原有Excel(不存在则新建),追加新数据后保存,避免覆盖原有内容。
修改后的完整代码
import tkinter as tk from tkinter import filedialog, messagebox from tkinter.ttk import Combobox import pandas as pd import os # 命令函数 def load(): path = filedialog.askopenfilename(filetypes=[("Excel文件", "*.xlsx")]) if path: df = pd.read_excel(path) print(df) def save(): # 从正确的控件获取输入值 mese = cb1.get() altezza = tb3.get("1.0", tk.END).strip() peso = tb4.get("1.0", tk.END).strip() mmagra = tb5.get("1.0", tk.END).strip() mgrassa = tb6.get("1.0", tk.END).strip() utente = combobox.get() # 检查必填项 if not all([mese, altezza, peso, mmagra, mgrassa, utente]): messagebox.showwarning("警告", "请填写所有字段") return # 构造新数据 new_data = pd.DataFrame({ "Mese": [mese], "Altezza": [altezza], "Peso": [peso], "Massa Magra": [mmagra], "Massa Grassa": [mgrassa], "Utente": [utente] }) excel_path = r'C:\Users\lricci\Desktop\SERVER\web\Gym Tracker\Gym Tracker v1.0\track.xlsx' # 检查文件是否存在,存在则追加,不存在则新建 if os.path.exists(excel_path): existing_df = pd.read_excel(excel_path) combined_df = pd.concat([existing_df, new_data], ignore_index=True) else: combined_df = new_data # 保存数据 combined_df.to_excel(excel_path, index=False) messagebox.showinfo("成功", "数据已保存") # 清空输入框 delete() def delete(): cb1.set("") tb3.delete("1.0", tk.END) tb4.delete("1.0", tk.END) tb5.delete("1.0", tk.END) tb6.delete("1.0", tk.END) combobox.set("") # 主窗口 windows = tk.Tk() windows.geometry("400x350") windows.title("Gym Tracker") windows.resizable(False, False) # 界面元素 frame1 = Frame(windows, width=150, height=30, highlightcolor="white", highlightbackground="black", highlightthickness=1) frame1.place(x=120, y=2) label1 = Label(windows, text="GYM TRACKER") label1.place(x=150, y=7) frame2 = Frame(windows, width=500, height=1, highlightcolor="white", highlightbackground="black", highlightthickness=1) frame2.place(x=2, y=45) # 月份下拉框 label2 = Label(windows, text="Mese") label2.place(x=110, y=60) cb1 = Combobox(windows, values=['Gennaio', 'Febbraio', 'Marzo', 'Aprile', 'Maggio', 'Giugno','Luglio', 'Agosto', 'Settembre', 'Ottobre', 'Novembre', 'Dicembre']) cb1.place(x=200, y=60) # 身高文本框 label3 = Label(windows, text="Altezza") label3.place(x=110, y=90) tb3 = Text(windows, width=17, height=1) tb3.place(x=200, y=90) # 体重文本框 label4 = Label(windows, text="Peso") label4.place(x=110, y=120) tb4 = Text(windows, width=17, height=1) tb4.place(x=200, y=120) # 瘦体重文本框 label5 = Label(windows, text="Massa Magra") label5.place(x=110, y=150) tb5 = Text(windows, width=17, height=1) tb5.place(x=200, y=150) # 体脂文本框 label6 = Label(windows, text="Massa Grassa") label6.place(x=110, y=180) tb6 = Text(windows, width=17, height=1) tb6.place(x=200, y=180) # 用户下拉框 label7 = Label(windows, text="Utente") label7.place(x=110, y=210) combobox = Combobox(windows, values=['Erika', 'Lorenzo']) combobox.place(x=200, y=210) # 按钮 btdelete = tk.Button(windows, text="Elimina", command=delete, width=8, height=1) btdelete.place(x=170, y=310) btload = tk.Button(windows, text="Load", width=8, height=1, command=load) btload.place(x=300, y=310) btsave = tk.Button(windows, text="Salva", width=8, height=1, command=save) btsave.place(x=50, y=310) windows.mainloop()
额外说明
- 移除了冗余的导入模块,只保留必要的库。
- 添加了必填项检查,避免保存空数据。
- 保存后自动清空输入框,提升使用体验。
- 用Pandas处理Excel更简洁,避免了openpyxl的繁琐操作。
内容的提问来源于stack exchange,提问作者snorky
相关产品推荐
相关产品推荐

