import tkinter as tk
from tkinter import ttk, filedialog, messagebox
from PIL import Image, ImageTk, ImageDraw, ImageFont
import os

# 主程序类
class StudentIDGenerator:
    def __init__(self, root):
        self.root = root
        self.root.title("学生证件生成器")
        self.root.geometry("600x550")
        self.root.resizable(False, False)

        # 变量存储
        self.name = tk.StringVar()
        self.id_num = tk.StringVar()
        self.grade = tk.StringVar()
        self.major = tk.StringVar()
        self.photo_path = ""  # 照片路径
        self.id_image = None  # 生成的证件图片

        # 创建界面
        self.create_widgets()

    def create_widgets(self):
        # 标题
        title_label = ttk.Label(self.root, text="学生证件信息填写", font=("微软雅黑", 16, "bold"))
        title_label.pack(pady=15)

        # 表单框架
        form_frame = ttk.Frame(self.root)
        form_frame.pack(pady=10, padx=20, fill="x")

        # 姓名
        ttk.Label(form_frame, text="姓 名：", font=("微软雅黑", 12)).grid(row=0, column=0, sticky="w", pady=8)
        ttk.Entry(form_frame, textvariable=self.name, font=("微软雅黑", 12), width=30).grid(row=0, column=1, pady=8)

        # 学号
        ttk.Label(form_frame, text="学 号：", font=("微软雅黑", 12)).grid(row=1, column=0, sticky="w", pady=8)
        ttk.Entry(form_frame, textvariable=self.id_num, font=("微软雅黑", 12), width=30).grid(row=1, column=1, pady=8)

        # 班级
        ttk.Label(form_frame, text="班 级：", font=("微软雅黑", 12)).grid(row=2, column=0, sticky="w", pady=8)
        ttk.Entry(form_frame, textvariable=self.grade, font=("微软雅黑", 12), width=30).grid(row=2, column=1, pady=8)

        # 专业
        ttk.Label(form_frame, text="专 业：", font=("微软雅黑", 12)).grid(row=3, column=0, sticky="w", pady=8)
        ttk.Entry(form_frame, textvariable=self.major, font=("微软雅黑", 12), width=30).grid(row=3, column=1, pady=8)

        # 照片区域
        photo_frame = ttk.LabelFrame(self.root, text="证件照", padding=10)
        photo_frame.pack(pady=10, padx=20, fill="x")

        self.photo_label = ttk.Label(photo_frame, text="未上传照片", width=20, relief="solid")
        self.photo_label.pack(pady=5)

        ttk.Button(photo_frame, text="上传证件照", command=self.upload_photo).pack()

        # 按钮区域
        btn_frame = ttk.Frame(self.root)
        btn_frame.pack(pady=15)

        ttk.Button(btn_frame, text="生成学生证", command=self.generate_id, width=15).grid(row=0, column=0, padx=10)
        ttk.Button(btn_frame, text="保存图片", command=self.save_id, width=15).grid(row=0, column=1, padx=10)

        # 预览区域
        preview_label = ttk.Label(self.root, text="学生证预览", font=("微软雅黑", 12, "bold"))
        preview_label.pack()

        self.preview_canvas = ttk.Label(self.root, relief="solid")
        self.preview_canvas.pack(pady=5)

    # 上传证件照
    def upload_photo(self):
        file_path = filedialog.askopenfilename(
            title="选择证件照",
            filetypes=[("图片文件", "*.jpg *.jpeg *.png *.bmp")]
        )
        if file_path:
            self.photo_path = file_path
            # 显示缩略图
            img = Image.open(file_path).resize((120, 160), Image.Resampling.LANCZOS)
            self.photo_tk = ImageTk.PhotoImage(img)
            self.photo_label.config(image=self.photo_tk, text="")

    # 生成学生证
    def generate_id(self):
        # 校验输入
        if not all([self.name.get(), self.id_num.get(), self.grade.get(), self.major.get()]):
            messagebox.showerror("错误", "请填写完整信息！")
            return
        if not self.photo_path:
            messagebox.showerror("错误", "请上传证件照！")
            return

        # 创建学生证画布（标准尺寸）
        id_card = Image.new("RGB", (450, 280), "white")
        draw = ImageDraw.Draw(id_card)

        # 绘制边框
        draw.rectangle([(10, 10), (440, 270)], outline="blue", width=3)

        # 绘制标题
        try:
            font_title = ImageFont.truetype("simhei.ttf", 28)
            font_text = ImageFont.truetype("simhei.ttf", 20)
        except:
            font_title = ImageFont.load_default(size=28)
            font_text = ImageFont.load_default(size=20)

        draw.text((150, 25), "学 生 证", fill="red", font=font_title)

        # 粘贴照片
        try:
            photo = Image.open(self.photo_path).resize((120, 160), Image.Resampling.LANCZOS)
            id_card.paste(photo, (40, 80))
        except:
            messagebox.showerror("错误", "照片加载失败！")
            return

        # 绘制学生信息
        draw.text((200, 90), f"姓    名：{self.name.get()}", fill="black", font=font_text)
        draw.text((200, 130), f"学    号：{self.id_num.get()}", fill="black", font=font_text)
        draw.text((200, 170), f"班    级：{self.grade.get()}", fill="black", font=font_text)
        draw.text((200, 210), f"专    业：{self.major.get()}", fill="black", font=font_text)

        # 保存并显示预览
        self.id_image = id_card
        preview_img = id_card.resize((360, 224), Image.Resampling.LANCZOS)
        self.preview_tk = ImageTk.PhotoImage(preview_img)
        self.preview_canvas.config(image=self.preview_tk)

        messagebox.showinfo("成功", "学生证生成完成！")

    # 保存学生证图片
    def save_id(self):
        if not self.id_image:
            messagebox.showerror("错误", "先生成学生证再保存！")
            return

        save_path = filedialog.asksaveasfilename(
            defaultextension=".png",
            filetypes=[("PNG图片", "*.png"), ("JPG图片", "*.jpg")],
            title="保存学生证"
        )
        if save_path:
            self.id_image.save(save_path)
            messagebox.showinfo("成功", f"学生证已保存至：\n{save_path}")

# 运行程序
if __name__ == "__main__":
    root = tk.Tk()
    app = StudentIDGenerator(root)
    root.mainloop()