Tkinter中点击按钮后图表无法自动更新?代码问题求助
解决Tkinter中Matplotlib图表点击按钮不更新的问题
你的代码核心问题是:点击按钮后只清空了图表,但没有重新读取新数据、重新绘制图表,也没正确刷新Tkinter里的Matplotlib画布组件。按以下方案修改即可解决:
关键修改点
- 把绘制图表的逻辑封装成独立函数,初始化和更新时都能调用
- 在
enter_data()中保存数据后,调用更新函数并刷新画布
修改后的完整代码
import tkinter as tk from tkinter import ttk from tkcalendar import DateEntry import openpyxl import matplotlib.pyplot as plt from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg import matplotlib.dates as mdates import pandas as pd window = tk.Tk() window.title("MY Weight") frame = tk.Frame(window) frame.pack() # 定义全局变量方便函数调用 figure = plt.Figure(figsize=(10,5),dpi=130) figure_plot = figure.add_subplot(1,1,1) line_graph = None filepath = "C:/Users/shaha/OneDrive/Desktop/Projects/weight.xlsx" # 封装图表更新函数 def update_graph(): # 清空子图 figure_plot.clear() # 重新读取Excel最新数据 weight = pd.read_excel(filepath) # 转换日期格式,确保x轴正确识别日期 weight['date'] = pd.to_datetime(weight['date'], format='%d/%m/%Y') # 绘制新图表 weight.plot(x='date',y='weight',kind='line',legend=True ,ax=figure_plot,color="purple",fontsize=6) figure_plot.set_ylabel("Weight/Calories") # 设置日期显示格式 figure_plot.xaxis.set_major_locator(mdates.DayLocator(interval=4)) date_format = mdates.DateFormatter('%d/%m/%Y') figure_plot.xaxis.set_major_formatter(date_format) figure.autofmt_xdate(rotation=45) # 刷新Tkinter画布 line_graph.draw() # 数据录入函数 def enter_data(): phase = phase_combobox.get() date1 = weight_date.get() weight = currently_weight_entry.get() # 写入Excel workbook = openpyxl.load_workbook(filepath) sheet = workbook.active sheet.append([phase,date1,int(weight)]) workbook.save(filepath) # 更新图表 update_graph() # 清空输入框(可选优化) currently_weight_entry.delete(0, tk.END) # 体重信息录入区 info_weight= tk.LabelFrame(frame,text="Weight Information") info_weight.grid(row=0,column=0) phase_label = tk.Label(info_weight,text="Currently Phase") phase_label.grid(row=0,column=0,padx=10,pady=10) phase_combobox = ttk.Combobox(info_weight,values=['Bulk',"Cut",'Maintain']) phase_combobox.grid(row=1,column=0,padx=10,pady=10) weight_date_label = tk.Label(info_weight,text="Date of weighing") weight_date_label.grid(row=2,column=0,padx=10,pady=10) sel=tk.StringVar() weight_date = DateEntry(info_weight,selectmode='day',date_pattern='d/m/Y',textvariable=sel,locale='en_US') weight_date.grid(row=3,column=0,padx=10,pady=10) currently_weight = tk.Label(info_weight,text="Weight") currently_weight.grid(row=4,column=0,padx=10,pady=10) currently_weight_entry = tk.Entry(info_weight) currently_weight_entry.grid(row=5,column=0,padx=10,pady=10) # 录入按钮 button = tk.Button(info_weight,text='ENTER',command=enter_data) button.grid(row=6,column=0,sticky='news',padx=10,pady=10) # 图表展示区 info_graph = tk.LabelFrame(frame) info_graph.grid(row=0,column=1) line_graph = FigureCanvasTkAgg(figure,info_graph) line_graph.get_tk_widget().pack(side=tk.LEFT,fill=tk.BOTH) # 初始化加载图表 update_graph() window.mainloop()
额外说明
update_graph()函数统一负责读取最新数据、绘制图表和刷新画布,避免代码重复- 强制转换日期格式为datetime,防止x轴日期显示异常
- 使用
line_graph.draw()刷新Tkinter中的Matplotlib画布,这是正确的刷新方式 - 新增清空输入框的逻辑,提升录入体验
内容的提问来源于stack exchange,提问作者Haymon
相关产品推荐
相关产品推荐

