import tkinter as tk
from tkinter import ttk, messagebox

class ScoreGUI:
    def __init__(self, root):
        self.root = root
        self.root.title("成绩走势图(纯tkinter)")
        self.root.geometry("900x680")
        self.names = []
        self.scores = []
        self.create_ui()

    def create_ui(self):
        # 输入区
        frame_input = ttk.LabelFrame(self.root, text="录入成绩")
        frame_input.pack(fill="x", padx=10, pady=4)

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

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

        ttk.Button(frame_input, text="添加", command=self.add_data).grid(row=0, column=4, padx=6)
        ttk.Button(frame_input, text="绘制图表", command=self.draw).grid(row=0, column=5, padx=6)
        ttk.Button(frame_input, text="清空全部", command=self.clear).grid(row=0, column=6, padx=6)

        # 数据显示
        frame_data = ttk.LabelFrame(self.root, text="已录入数据")
        frame_data.pack(fill="x", padx=10, pady=4)
        self.txt_data = tk.Text(frame_data, height=4)
        self.txt_data.pack(fill="x", padx=5)

        # 画布绘图区
        frame_canvas = ttk.LabelFrame(self.root, text="成绩折线图")
        frame_canvas.pack(fill="both", expand=True, padx=10, pady=4)
        self.canvas = tk.Canvas(frame_canvas, bg="white")
        self.canvas.pack(fill="both", expand=True)

    def add_data(self):
        name = self.ent_name.get().strip()
        s_text = self.ent_score.get().strip()
        if not name:
            messagebox.showwarning("提示", "请输入考试名称")
            return
        if not s_text:
            messagebox.showwarning("提示", "请输入分数")
            return
        try:
            score = float(s_text)
            if not 0 <= score <= 100:
                messagebox.showerror("错误", "分数范围0~100")
                return
        except:
            messagebox.showerror("错误", "分数必须是数字")
            return
        self.names.append(name)
        self.scores.append(score)
        self.txt_data.insert(tk.END, f"{name}：{score}分\n")
        self.txt_data.see(tk.END)
        self.ent_name.delete(0, tk.END)
        self.ent_score.delete(0, tk.END)

    def draw(self):
        self.canvas.delete("all")
        n = len(self.names)
        if n == 0:
            messagebox.showinfo("提示", "请先录入成绩！")
            return
        w = self.canvas.winfo_width()
        h = self.canvas.winfo_height()
        margin = 40
        # 坐标轴
        self.canvas.create_line(margin, margin, margin, h-margin, fill="black", width=2)
        self.canvas.create_line(margin, h-margin, w-margin, h-margin, fill="black", width=2)
        # Y刻度 0/20/40/60/80/100
        for i in range(0, 101, 20):
            y = h - margin - (i / 100) * (h - margin*2)
            self.canvas.create_line(margin-5, y, margin, y, fill="black")
            self.canvas.create_text(margin-10, y, text=str(i), anchor="e")
        # 计算每个点坐标
        points = []
        step_x = (w - margin*2) / (n - 1) if n > 1 else 0
        for idx, s in enumerate(self.scores):
            x = margin + idx * step_x
            y = h - margin - (s / 100) * (h - margin*2)
            points.append((x, y))
            # 圆点
            self.canvas.create_oval(x-5, y-5, x+5, y+5, fill="#2E86AB")
            # 文字标注分数
            self.canvas.create_text(x, y-12, text=str(s), font=("微软雅黑",9))
            # X轴考试名称
            self.canvas.create_text(x, h-margin+15, text=self.names[idx], font=("微软雅黑",9))
        # 连线
        if len(points) > 1:
            flat = []
            for p in points:
                flat.append(p[0])
                flat.append(p[1])
            self.canvas.create_line(*flat, fill="#2E86AB", width=2)

    def clear(self):
        self.names.clear()
        self.scores.clear()
        self.txt_data.delete(1.0, tk.END)
        self.canvas.delete("all")
        messagebox.showinfo("完成", "数据和图表已清空")

if __name__ == "__main__":
    win = tk.Tk()
    app = ScoreGUI(win)
    win.mainloop()