import tkinter as tk
from tkinter import ttk, messagebox
import matplotlib.pyplot as plt
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg

# 设置中文显示，防止图表文字乱码
plt.rcParams["font.family"] = ["SimHei", "WenQuanYi Micro Hei", "Heiti TC"]
plt.rcParams["axes.unicode_minus"] = False


class ScoreChartGUI:
    def __init__(self, root):
        self.root = root
        self.root.title("成绩走势图")
        self.root.geometry("800x600")

        # 存储数据
        self.test_labels = []  # 考试名称/轮次
        self.score_data = []   # 对应分数

        # 构建界面布局
        self.create_widgets()
        # 初始化画布
        self.init_plot()

    def create_widgets(self):
        # 顶部输入区域
        frame_input = ttk.Frame(self.root, padding=10)
        frame_input.pack(fill=tk.X)

        ttk.Label(frame_input, text="考试名称：").grid(row=0, column=0, padx=5)
        self.entry_name = ttk.Entry(frame_input, width=15)
        self.entry_name.grid(row=0, column=1, padx=5)

        ttk.Label(frame_input, text="分数：").grid(row=0, column=2, padx=5)
        self.entry_score = ttk.Entry(frame_input, width=10)
        self.entry_score.grid(row=0, column=3, padx=5)

        btn_add = ttk.Button(frame_input, text="添加成绩", command=self.add_score)
        btn_add.grid(row=0, column=4, padx=5)

        btn_clear = ttk.Button(frame_input, text="清空所有", command=self.clear_all)
        btn_clear.grid(row=0, column=5, padx=5)

        btn_save = ttk.Button(frame_input, text="保存图片", command=self.save_image)
        btn_save.grid(row=0, column=6, padx=5)

        # 图表容器
        self.frame_chart = ttk.Frame(self.root)
        self.frame_chart.pack(fill=tk.BOTH, expand=True, padx=10, pady=10)

    def init_plot(self):
        # 创建画布与子图
        self.fig, self.ax = plt.subplots(figsize=(8, 5), dpi=100)
        self.canvas = FigureCanvasTkAgg(self.fig, master=self.frame_chart)
        self.canvas_widget = self.canvas.get_tk_widget()
        self.canvas_widget.pack(fill=tk.BOTH, expand=True)

    def refresh_chart(self):
        # 清空旧图像重新绘制
        self.ax.clear()
        if len(self.test_labels) > 0:
            self.ax.plot(self.test_labels, self.score_data, marker='o', color='#2E86AB', linewidth=2, markersize=7)
            # 在每个点标注分数
            for x, y in zip(self.test_labels, self.score_data):
                self.ax.text(x, y + 1, str(y), ha="center")

        self.ax.set_title("成绩变化走势图", fontsize=14)
        self.ax.set_xlabel("考试轮次")
        self.ax.set_ylabel("分数")
        self.ax.grid(True, alpha=0.3)
        self.ax.set_ylim(0, 105)  # 满分100，可自行修改

        self.canvas.draw()

    def add_score(self):
        name = self.entry_name.get().strip()
        score_text = self.entry_score.get().strip()
        if not name or not score_text:
            messagebox.showwarning("提示", "考试名称和分数不能为空！")
            return
        try:
            score = float(score_text)
            if not (0 <= score <= 100):
                messagebox.showwarning("提示", "分数范围0~100！")
                return
        except ValueError:
            messagebox.showerror("错误", "分数必须输入数字！")
            return

        self.test_labels.append(name)
        self.score_data.append(score)

        # 清空输入框
        self.entry_name.delete(0, tk.END)
        self.entry_score.delete(0, tk.END)
        self.refresh_chart()

    def clear_all(self):
        self.test_labels.clear()
        self.score_data.clear()
        self.refresh_chart()

    def save_image(self):
        self.fig.savefig("成绩走势图.png", dpi=150, bbox_inches="tight")
        messagebox.showinfo("完成", "图表已保存为：成绩走势图.png")


if __name__ == "__main__":
    window = tk.Tk()
    app = ScoreChartGUI(window)
    window.mainloop()