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

class GradeTracker:
    def __init__(self, root):
        self.root = root
        self.root.title("学生成绩走势分析工具")
        self.root.geometry("900x600")

        # 存储数据
        self.subjects = []
        self.scores = []

        self._setup_ui()

    def _setup_ui(self):
        # --- 左侧输入区域 ---
        left_frame = tk.Frame(self.root, width=300, padx=20, pady=20)
        left_frame.pack(side="left", fill="y")

        tk.Label(left_frame, text="成绩录入", font=("微软雅黑", 14, "bold")).pack(pady=10)

        tk.Label(left_frame, text="考试/科目名称:").pack(anchor="w")
        self.subject_entry = tk.Entry(left_frame, font=("微软雅黑", 10))
        self.subject_entry.pack(fill="x", pady=5)

        tk.Label(left_frame, text="分数:").pack(anchor="w")
        self.score_entry = tk.Entry(left_frame, font=("微软雅黑", 10))
        self.score_entry.pack(fill="x", pady=5)

        tk.Button(left_frame, text="添加成绩", command=self._add_grade, bg="#4CAF50", fg="white").pack(fill="x", pady=10)
        tk.Button(left_frame, text="清空数据", command=self._clear_data, bg="#f44336", fg="white").pack(fill="x")

        # 数据列表显示
        tk.Label(left_frame, text="已录入数据:", font=("微软雅黑", 10, "bold")).pack(anchor="w", pady=(20, 5))
        self.tree = ttk.Treeview(left_frame, columns=("Subject", "Score"), show="headings", height=10)
        self.tree.heading("Subject", text="科目/时间")
        self.tree.heading("Score", text="分数")
        self.tree.column("Subject", width=120)
        self.tree.column("Score", width=60)
        self.tree.pack(fill="both", expand=True)

        # --- 右侧图表区域 ---
        self.right_frame = tk.Frame(self.root, bg="white")
        self.right_frame.pack(side="right", expand=True, fill="both", padx=10, pady=10)
        
        # 初始化一个空白图表
        self.fig = Figure(figsize=(6, 5), dpi=100)
        self.ax = self.fig.add_subplot(111)
        self.ax.set_title("成绩走势图")
        self.ax.set_xlabel("科目/时间")
        self.ax.set_ylabel("分数")
        
        self.canvas = FigureCanvasTkAgg(self.fig, master=self.right_frame)
        self.canvas.draw()
        self.canvas.get_tk_widget().pack(side="top", fill="both", expand=True)

    def _add_grade(self):
        subject = self.subject_entry.get().strip()
        score_str = self.score_entry.get().strip()

        if not subject or not score_str:
            messagebox.showwarning("输入错误", "请输入科目和分数")
            return

        try:
            score = float(score_str)
            if score < 0 or score > 150:
                raise ValueError
        except ValueError:
            messagebox.showerror("错误", "分数必须是0-150之间的数字")
            return

        # 更新数据源
        self.subjects.append(subject)
        self.scores.append(score)
        
        # 更新列表显示
        self.tree.insert("", "end", values=(subject, score))
        
        # 清空输入框
        self.subject_entry.delete(0, tk.END)
        self.score_entry.delete(0, tk.END)
        
        # 重新绘图
        self._update_chart()

    def _update_chart(self):
        self.ax.clear() # 清除旧图
        
        # 设置中文字体（防止乱码，根据系统不同可能需要微调）
        plt.rcParams['font.sans-serif'] = ['SimHei'] 
        plt.rcParams['axes.unicode_minus'] = False

        if self.subjects:
            # 绘制折线图
            self.ax.plot(self.subjects, self.scores, marker='o', linestyle='-', color='b', linewidth=2)
            # 添加数值标签
            for i, txt in enumerate(self.scores):
                self.ax.annotate(txt, (self.subjects[i], self.scores[i]), textcoords="offset points", xytext=(0,10), ha='center')
            
            self.ax.set_title("成绩变化趋势", fontsize=14)
            self.ax.set_ylim(0, max(self.scores) + 20) # 动态设置Y轴高度
            self.ax.grid(True, linestyle='--', alpha=0.6)

        self.canvas.draw()

    def _clear_data(self):
        if messagebox.askyesno("确认", "确定要清空所有数据吗？"):
            self.subjects = []
            self.scores = []
            for item in self.tree.get_children():
                self.tree.delete(item)
            self._update_chart()

if __name__ == "__main__":
    root = tk.Tk()
    # 尝试解决Windows高分屏模糊问题
    try:
        from ctypes import windll
        windll.shcore.SetProcessDpiAwareness(1)
    except:
        pass
    app = GradeTracker(root)
    root.mainloop()