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

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

class ScoreTrendGUI:
    def __init__(self, root):
        self.root = root
        self.root.title("学生成绩走势图")
        self.root.geometry("900x650")

        # 存储数据：科目列表、历次考试分数
        self.subjects = []
        self.score_data = {}
        self.exam_times = []  # 考试次数（第1次、第2次...）
        self.count = 1

        # 左侧输入面板
        left_frame = tk.Frame(root, width=280, padx=10, pady=10)
        left_frame.pack(side=tk.LEFT, fill=tk.Y)

        # 科目输入
        ttk.Label(left_frame, text="输入科目名称：").pack(anchor="w")
        self.sub_entry = ttk.Entry(left_frame, width=25)
        self.sub_entry.pack(pady=4)
        ttk.Button(left_frame, text="添加科目", command=self.add_subject).pack(pady=2, fill=tk.X)

        # 成绩输入
        ttk.Label(left_frame, text=f"第{self.count}次考试成绩：").pack(anchor="w", pady=(10,0))
        self.score_text = tk.Text(left_frame, height=8, width=30)
        self.score_text.pack(pady=5)
        # 修复：font放在Label创建时，不是pack里
        ttk.Label(left_frame, text="格式：科目:分数，一行一条", font=("微软雅黑",8)).pack(anchor="w")

        # 功能按钮
        btn_frame = tk.Frame(left_frame)
        btn_frame.pack(pady=10, fill=tk.X)
        ttk.Button(btn_frame, text="录入本次成绩", command=self.save_score).grid(row=0,column=0,sticky="ew")
        ttk.Button(btn_frame, text="生成走势图", command=self.draw_chart).grid(row=0,column=1,sticky="ew")
        btn_frame.columnconfigure(0,weight=1)
        btn_frame.columnconfigure(1,weight=1)

        ttk.Button(left_frame, text="清空所有数据", command=self.clear_all).pack(pady=3, fill=tk.X)
        ttk.Button(left_frame, text="保存图表到本地", command=self.save_pic).pack(pady=3, fill=tk.X)

        # 右侧绘图区域
        right_frame = tk.Frame(root, padx=5, pady=5)
        right_frame.pack(side=tk.RIGHT, expand=True, fill=tk.BOTH)
        self.fig, self.ax = plt.subplots(figsize=(7,5))
        self.canvas = FigureCanvasTkAgg(self.fig, master=right_frame)
        self.canvas_widget = self.canvas.get_tk_widget()
        self.canvas_widget.pack(expand=True, fill=tk.BOTH)

    def add_subject(self):
        """新增科目"""
        sub = self.sub_entry.get().strip()
        if not sub:
            messagebox.showwarning("提示", "请输入科目名称！")
            return
        if sub in self.subjects:
            messagebox.showinfo("提示", "该科目已存在")
            return
        self.subjects.append(sub)
        self.score_data[sub] = []
        self.sub_entry.delete(0, tk.END)
        messagebox.showinfo("成功", f"已添加科目：{sub}")

    def save_score(self):
        """读取文本框成绩并保存"""
        content = self.score_text.get("1.0", tk.END).strip()
        if not content:
            messagebox.showwarning("警告", "未填写任何成绩！")
            return
        lines = content.splitlines()
        temp_dict = {}
        for line in lines:
            if ":" not in line:
                continue
            sub, scr = line.split(":", 1)
            sub = sub.strip()
            try:
                score = float(scr.strip())
                if 0 <= score <= 100:
                    temp_dict[sub] = score
            except ValueError:
                messagebox.showerror("错误", f"「{line}」分数格式错误，必须是数字")
                return
        # 补全缺考科目分数为0
        for s in self.subjects:
            if s not in temp_dict:
                temp_dict[s] = 0
        # 存入数据
        for s in self.subjects:
            self.score_data[s].append(temp_dict[s])
        self.exam_times.append(f"第{self.count}次")
        self.count += 1
        self.score_text.delete("1.0", tk.END)
        messagebox.showinfo("录入完成", f"第{self.count-1}次成绩已保存")

    def draw_chart(self):
        """绘制折线走势图"""
        if not self.exam_times:
            messagebox.showwarning("无数据", "请先录入至少一次考试成绩")
            return
        self.ax.clear()
        # 每个科目画一条折线
        for sub in self.subjects:
            self.ax.plot(self.exam_times, self.score_data[sub], marker="o", label=sub, linewidth=2)
        self.ax.set_title("各科成绩走势折线图", fontsize=14)
        self.ax.set_xlabel("考试批次")
        self.ax.set_ylabel("分数")
        self.ax.legend(loc="best")
        self.ax.grid(alpha=0.3)
        self.canvas.draw()

    def clear_all(self):
        """重置全部数据与画布"""
        self.subjects = []
        self.score_data = {}
        self.exam_times = []
        self.count = 1
        self.score_text.delete("1.0", tk.END)
        self.sub_entry.delete(0, tk.END)
        self.ax.clear()
        self.canvas.draw()
        messagebox.showinfo("清空", "所有数据已重置")

    def save_pic(self):
        """把图表保存为png图片"""
        if not self.exam_times:
            messagebox.showwarning("提示", "没有可保存的图表")
            return
        self.fig.savefig("成绩走势图.png", dpi=300, bbox_inches="tight")
        messagebox.showinfo("保存成功", "图片已保存为 成绩走势图.png")

if __name__ == "__main__":
    root = tk.Tk()
    app = ScoreTrendGUI(root)
    root.mainloop()