You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.27 12:23:23