|
|
|
|
@ -0,0 +1,775 @@
|
|
|
|
|
#!/usr/bin/env python3
|
|
|
|
|
# -*- coding: utf-8 -*-
|
|
|
|
|
|
|
|
|
|
"""
|
|
|
|
|
主应用模块
|
|
|
|
|
"""
|
|
|
|
|
|
|
|
|
|
import tkinter as tk
|
|
|
|
|
from tkinter import messagebox, ttk
|
|
|
|
|
import random
|
|
|
|
|
from typing import List, Optional
|
|
|
|
|
|
|
|
|
|
from user_manager import UserManager
|
|
|
|
|
from question_bank import QuestionBank
|
|
|
|
|
from quiz import Quiz
|
|
|
|
|
from question_generator import Expression
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class MathQuizApp:
|
|
|
|
|
"""
|
|
|
|
|
数学测验应用程序主类
|
|
|
|
|
"""
|
|
|
|
|
|
|
|
|
|
def __init__(self, root: tk.Tk):
|
|
|
|
|
"""
|
|
|
|
|
初始化应用程序
|
|
|
|
|
|
|
|
|
|
@param root: Tk根窗口
|
|
|
|
|
"""
|
|
|
|
|
self.root = root
|
|
|
|
|
self.root.title("数学练习系统")
|
|
|
|
|
self.root.geometry("700x600")
|
|
|
|
|
self.root.resizable(True, True)
|
|
|
|
|
self.root.configure(bg="#f0f0f0")
|
|
|
|
|
|
|
|
|
|
# 初始化系统组件
|
|
|
|
|
self.user_manager = UserManager()
|
|
|
|
|
self.question_bank = QuestionBank()
|
|
|
|
|
|
|
|
|
|
# 设置样式
|
|
|
|
|
self.setup_styles()
|
|
|
|
|
|
|
|
|
|
# 创建不同的界面框架
|
|
|
|
|
self.login_frame = tk.Frame(self.root, bg="#f0f0f0")
|
|
|
|
|
self.register_frame = tk.Frame(self.root, bg="#f0f0f0")
|
|
|
|
|
self.set_password_frame = tk.Frame(self.root, bg="#f0f0f0")
|
|
|
|
|
self.main_menu_frame = tk.Frame(self.root, bg="#f0f0f0")
|
|
|
|
|
self.quiz_setup_frame = tk.Frame(self.root, bg="#f0f0f0")
|
|
|
|
|
self.quiz_frame = tk.Frame(self.root, bg="#f0f0f0")
|
|
|
|
|
self.result_frame = tk.Frame(self.root, bg="#f0f0f0")
|
|
|
|
|
self.change_password_frame = tk.Frame(self.root, bg="#f0f0f0")
|
|
|
|
|
self.delete_account_frame = tk.Frame(self.root, bg="#f0f0f0") # 添加删除账户框架
|
|
|
|
|
|
|
|
|
|
# 初始化应用状态
|
|
|
|
|
self.current_quiz: Optional[Quiz] = None
|
|
|
|
|
self.current_level = ""
|
|
|
|
|
self.question_count = 0
|
|
|
|
|
|
|
|
|
|
# 创建界面
|
|
|
|
|
self.create_widgets()
|
|
|
|
|
self.show_login_frame()
|
|
|
|
|
|
|
|
|
|
def setup_styles(self):
|
|
|
|
|
"""
|
|
|
|
|
设置界面样式
|
|
|
|
|
"""
|
|
|
|
|
self.title_font = ("Arial", 20, "bold")
|
|
|
|
|
self.header_font = ("Arial", 16, "bold")
|
|
|
|
|
self.normal_font = ("Arial", 12)
|
|
|
|
|
self.button_font = ("Arial", 11, "bold")
|
|
|
|
|
|
|
|
|
|
# 定义颜色方案
|
|
|
|
|
self.primary_color = "#4a6fa5"
|
|
|
|
|
self.secondary_color = "#6b8cbc"
|
|
|
|
|
self.accent_color = "#ff6b6b"
|
|
|
|
|
self.success_color = "#4caf50"
|
|
|
|
|
self.warning_color = "#ffc107"
|
|
|
|
|
self.danger_color = "#f44336"
|
|
|
|
|
self.light_bg = "#f8f9fa"
|
|
|
|
|
self.dark_text = "#333333"
|
|
|
|
|
|
|
|
|
|
def create_widgets(self):
|
|
|
|
|
"""
|
|
|
|
|
创建界面组件
|
|
|
|
|
"""
|
|
|
|
|
# 创建不同的界面框架
|
|
|
|
|
self.login_frame = tk.Frame(self.root, bg="#f0f0f0")
|
|
|
|
|
self.register_frame = tk.Frame(self.root, bg="#f0f0f0")
|
|
|
|
|
self.set_password_frame = tk.Frame(self.root, bg="#f0f0f0")
|
|
|
|
|
self.main_menu_frame = tk.Frame(self.root, bg="#f0f0f0")
|
|
|
|
|
self.quiz_setup_frame = tk.Frame(self.root, bg="#f0f0f0")
|
|
|
|
|
self.quiz_frame = tk.Frame(self.root, bg="#f0f0f0")
|
|
|
|
|
self.result_frame = tk.Frame(self.root, bg="#f0f0f0")
|
|
|
|
|
self.change_password_frame = tk.Frame(self.root, bg="#f0f0f0")
|
|
|
|
|
self.delete_account_frame = tk.Frame(self.root, bg="#f0f0f0") # 添加删除账户框架
|
|
|
|
|
|
|
|
|
|
def show_frame(self, frame: tk.Frame):
|
|
|
|
|
"""
|
|
|
|
|
显示指定的界面框架
|
|
|
|
|
|
|
|
|
|
@param frame: 要显示的框架
|
|
|
|
|
"""
|
|
|
|
|
# 隐藏所有框架
|
|
|
|
|
for f in [self.login_frame, self.register_frame, self.set_password_frame,
|
|
|
|
|
self.main_menu_frame, self.quiz_setup_frame, self.quiz_frame,
|
|
|
|
|
self.result_frame, self.change_password_frame, self.delete_account_frame]:
|
|
|
|
|
f.pack_forget()
|
|
|
|
|
|
|
|
|
|
# 显示指定框架
|
|
|
|
|
frame.pack(fill="both", expand=True)
|
|
|
|
|
|
|
|
|
|
def show_login_frame(self):
|
|
|
|
|
"""
|
|
|
|
|
显示登录界面
|
|
|
|
|
"""
|
|
|
|
|
# 清除之前的内容
|
|
|
|
|
for widget in self.login_frame.winfo_children():
|
|
|
|
|
widget.destroy()
|
|
|
|
|
|
|
|
|
|
# 创建登录界面
|
|
|
|
|
main_frame = tk.Frame(self.login_frame, bg="#ffffff", relief=tk.RAISED, bd=2)
|
|
|
|
|
main_frame.pack(pady=50, padx=50, fill="both", expand=True)
|
|
|
|
|
|
|
|
|
|
title_frame = tk.Frame(main_frame, bg=self.primary_color)
|
|
|
|
|
title_frame.pack(fill="x", pady=(0, 30))
|
|
|
|
|
tk.Label(title_frame, text="用户登录", font=self.title_font, bg=self.primary_color, fg="white").pack(pady=20)
|
|
|
|
|
|
|
|
|
|
form_frame = tk.Frame(main_frame, bg="#ffffff")
|
|
|
|
|
form_frame.pack(pady=10)
|
|
|
|
|
|
|
|
|
|
tk.Label(form_frame, text="用户名:", font=self.normal_font, bg="#ffffff").pack(pady=5, anchor="w")
|
|
|
|
|
self.login_email_entry = tk.Entry(form_frame, width=30, font=self.normal_font, relief=tk.FLAT, bd=5, bg="#f0f0f0")
|
|
|
|
|
self.login_email_entry.pack(pady=5)
|
|
|
|
|
|
|
|
|
|
tk.Label(form_frame, text="密码:", font=self.normal_font, bg="#ffffff").pack(pady=5, anchor="w")
|
|
|
|
|
self.login_password_entry = tk.Entry(form_frame, width=30, font=self.normal_font, show="*", relief=tk.FLAT, bd=5, bg="#f0f0f0")
|
|
|
|
|
self.login_password_entry.pack(pady=5)
|
|
|
|
|
|
|
|
|
|
button_frame = tk.Frame(main_frame, bg="#ffffff")
|
|
|
|
|
button_frame.pack(pady=20)
|
|
|
|
|
|
|
|
|
|
tk.Button(button_frame, text="登录", command=self.login, width=20, bg=self.primary_color, fg="white",
|
|
|
|
|
font=self.button_font, relief=tk.FLAT, bd=0, padx=10, pady=5).pack(pady=10)
|
|
|
|
|
tk.Button(button_frame, text="注册新用户", command=self.show_register_frame, width=20, bg=self.secondary_color, fg="white",
|
|
|
|
|
font=self.button_font, relief=tk.FLAT, bd=0, padx=10, pady=5).pack(pady=5)
|
|
|
|
|
tk.Button(button_frame, text="注销账户", command=self.show_delete_account_frame, width=20, bg=self.danger_color, fg="white",
|
|
|
|
|
font=self.button_font, relief=tk.FLAT, bd=0, padx=10, pady=5).pack(pady=5)
|
|
|
|
|
|
|
|
|
|
self.show_frame(self.login_frame)
|
|
|
|
|
|
|
|
|
|
def login(self):
|
|
|
|
|
"""
|
|
|
|
|
处理登录逻辑
|
|
|
|
|
"""
|
|
|
|
|
username = self.login_email_entry.get().strip()
|
|
|
|
|
password = self.login_password_entry.get()
|
|
|
|
|
|
|
|
|
|
if not username or not password:
|
|
|
|
|
messagebox.showerror("错误", "请输入用户名和密码")
|
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
if self.user_manager.login(username, password):
|
|
|
|
|
messagebox.showinfo("成功", "登录成功")
|
|
|
|
|
self.show_main_menu_frame()
|
|
|
|
|
# 错误信息在user_manager.login中已经显示
|
|
|
|
|
|
|
|
|
|
def show_register_frame(self):
|
|
|
|
|
"""
|
|
|
|
|
显示注册界面
|
|
|
|
|
"""
|
|
|
|
|
# 清除之前的内容
|
|
|
|
|
for widget in self.register_frame.winfo_children():
|
|
|
|
|
widget.destroy()
|
|
|
|
|
|
|
|
|
|
# 创建注册界面
|
|
|
|
|
main_frame = tk.Frame(self.register_frame, bg="#ffffff", relief=tk.RAISED, bd=2)
|
|
|
|
|
main_frame.pack(pady=30, padx=50, fill="both", expand=True)
|
|
|
|
|
|
|
|
|
|
title_frame = tk.Frame(main_frame, bg=self.primary_color)
|
|
|
|
|
title_frame.pack(fill="x", pady=(0, 20))
|
|
|
|
|
tk.Label(title_frame, text="用户注册", font=self.title_font, bg=self.primary_color, fg="white").pack(pady=20)
|
|
|
|
|
|
|
|
|
|
form_frame = tk.Frame(main_frame, bg="#ffffff")
|
|
|
|
|
form_frame.pack(pady=10)
|
|
|
|
|
|
|
|
|
|
tk.Label(form_frame, text="用户名:", font=self.normal_font, bg="#ffffff").pack(pady=5, anchor="w")
|
|
|
|
|
self.register_username_entry = tk.Entry(form_frame, width=30, font=self.normal_font, relief=tk.FLAT, bd=5, bg="#f0f0f0")
|
|
|
|
|
self.register_username_entry.pack(pady=5)
|
|
|
|
|
|
|
|
|
|
tk.Label(form_frame, text="邮箱:", font=self.normal_font, bg="#ffffff").pack(pady=5, anchor="w")
|
|
|
|
|
self.register_email_entry = tk.Entry(form_frame, width=30, font=self.normal_font, relief=tk.FLAT, bd=5, bg="#f0f0f0")
|
|
|
|
|
self.register_email_entry.pack(pady=5)
|
|
|
|
|
|
|
|
|
|
tk.Button(form_frame, text="获取注册码", command=self.send_registration_code, width=20, bg=self.primary_color, fg="white",
|
|
|
|
|
font=self.button_font, relief=tk.FLAT, bd=0, padx=10, pady=5).pack(pady=10)
|
|
|
|
|
|
|
|
|
|
tk.Label(form_frame, text="注册码:", font=self.normal_font, bg="#ffffff").pack(pady=5, anchor="w")
|
|
|
|
|
self.registration_code_entry = tk.Entry(form_frame, width=30, font=self.normal_font, relief=tk.FLAT, bd=5, bg="#f0f0f0")
|
|
|
|
|
self.registration_code_entry.pack(pady=5)
|
|
|
|
|
|
|
|
|
|
button_frame = tk.Frame(main_frame, bg="#ffffff")
|
|
|
|
|
button_frame.pack(pady=20)
|
|
|
|
|
|
|
|
|
|
tk.Button(button_frame, text="验证注册码", command=self.verify_registration_code, width=20, bg=self.success_color, fg="white",
|
|
|
|
|
font=self.button_font, relief=tk.FLAT, bd=0, padx=10, pady=5).pack(pady=10)
|
|
|
|
|
tk.Button(button_frame, text="返回登录", command=self.show_login_frame, width=20, bg="#cccccc", fg=self.dark_text,
|
|
|
|
|
font=self.button_font, relief=tk.FLAT, bd=0, padx=10, pady=5).pack(pady=5)
|
|
|
|
|
|
|
|
|
|
self.show_frame(self.register_frame)
|
|
|
|
|
|
|
|
|
|
def send_registration_code(self):
|
|
|
|
|
"""
|
|
|
|
|
发送注册码
|
|
|
|
|
"""
|
|
|
|
|
username = self.register_username_entry.get().strip()
|
|
|
|
|
email = self.register_email_entry.get().strip()
|
|
|
|
|
|
|
|
|
|
if not username or not email:
|
|
|
|
|
messagebox.showerror("错误", "请输入用户名和邮箱")
|
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
if self.user_manager.register_user(email, username):
|
|
|
|
|
messagebox.showinfo("成功", "注册码已发送,请查收")
|
|
|
|
|
|
|
|
|
|
def verify_registration_code(self):
|
|
|
|
|
"""
|
|
|
|
|
验证注册码
|
|
|
|
|
"""
|
|
|
|
|
email = self.register_email_entry.get().strip()
|
|
|
|
|
code = self.registration_code_entry.get().strip()
|
|
|
|
|
|
|
|
|
|
if not email or not code:
|
|
|
|
|
messagebox.showerror("错误", "请输入邮箱和注册码")
|
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
if self.user_manager.verify_registration_code(email, code):
|
|
|
|
|
messagebox.showinfo("成功", "注册码验证成功,请设置密码")
|
|
|
|
|
self.show_set_password_frame(email)
|
|
|
|
|
|
|
|
|
|
def show_set_password_frame(self, email: str):
|
|
|
|
|
"""
|
|
|
|
|
显示设置密码界面
|
|
|
|
|
|
|
|
|
|
@param email: 用户邮箱
|
|
|
|
|
"""
|
|
|
|
|
# 清除之前的内容
|
|
|
|
|
for widget in self.set_password_frame.winfo_children():
|
|
|
|
|
widget.destroy()
|
|
|
|
|
|
|
|
|
|
# 创建设置密码界面
|
|
|
|
|
main_frame = tk.Frame(self.set_password_frame, bg="#ffffff", relief=tk.RAISED, bd=2)
|
|
|
|
|
main_frame.pack(pady=30, padx=50, fill="both", expand=True)
|
|
|
|
|
|
|
|
|
|
title_frame = tk.Frame(main_frame, bg=self.primary_color)
|
|
|
|
|
title_frame.pack(fill="x", pady=(0, 20))
|
|
|
|
|
tk.Label(title_frame, text="设置密码", font=self.title_font, bg=self.primary_color, fg="white").pack(pady=20)
|
|
|
|
|
|
|
|
|
|
form_frame = tk.Frame(main_frame, bg="#ffffff")
|
|
|
|
|
form_frame.pack(pady=10)
|
|
|
|
|
|
|
|
|
|
tk.Label(form_frame, text="邮箱: " + email, font=self.normal_font, bg="#ffffff").pack(pady=5, anchor="w")
|
|
|
|
|
|
|
|
|
|
tk.Label(form_frame, text="密码:", font=self.normal_font, bg="#ffffff", fg=self.primary_color).pack(pady=(10, 5), anchor="w")
|
|
|
|
|
tk.Label(form_frame, text="(6-10位,必须包含大小写字母和数字)", font=("Arial", 10), bg="#ffffff", fg="gray").pack(pady=5, anchor="w")
|
|
|
|
|
self.set_password_entry = tk.Entry(form_frame, width=30, font=self.normal_font, show="*", relief=tk.FLAT, bd=5, bg="#f0f0f0")
|
|
|
|
|
self.set_password_entry.pack(pady=5)
|
|
|
|
|
|
|
|
|
|
tk.Label(form_frame, text="确认密码:", font=self.normal_font, bg="#ffffff").pack(pady=5, anchor="w")
|
|
|
|
|
self.confirm_password_entry = tk.Entry(form_frame, width=30, font=self.normal_font, show="*", relief=tk.FLAT, bd=5, bg="#f0f0f0")
|
|
|
|
|
self.confirm_password_entry.pack(pady=5)
|
|
|
|
|
|
|
|
|
|
button_frame = tk.Frame(main_frame, bg="#ffffff")
|
|
|
|
|
button_frame.pack(pady=20)
|
|
|
|
|
|
|
|
|
|
tk.Button(button_frame, text="设置密码", command=lambda: self.set_password(email), width=20, bg=self.success_color, fg="white",
|
|
|
|
|
font=self.button_font, relief=tk.FLAT, bd=0, padx=10, pady=5).pack(pady=10)
|
|
|
|
|
tk.Button(button_frame, text="返回登录", command=self.show_login_frame, width=20, bg="#cccccc", fg=self.dark_text,
|
|
|
|
|
font=self.button_font, relief=tk.FLAT, bd=0, padx=10, pady=5).pack(pady=5)
|
|
|
|
|
|
|
|
|
|
self.show_frame(self.set_password_frame)
|
|
|
|
|
|
|
|
|
|
def set_password(self, email: str):
|
|
|
|
|
"""
|
|
|
|
|
设置密码
|
|
|
|
|
|
|
|
|
|
@param email: 用户邮箱
|
|
|
|
|
"""
|
|
|
|
|
password = self.set_password_entry.get()
|
|
|
|
|
confirm_password = self.confirm_password_entry.get()
|
|
|
|
|
|
|
|
|
|
if not password or not confirm_password:
|
|
|
|
|
messagebox.showerror("错误", "请输入密码和确认密码")
|
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
if password != confirm_password:
|
|
|
|
|
messagebox.showerror("错误", "两次输入的密码不一致")
|
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
if self.user_manager.set_password(email, password):
|
|
|
|
|
messagebox.showinfo("成功", "密码设置成功,请登录")
|
|
|
|
|
self.show_login_frame()
|
|
|
|
|
|
|
|
|
|
def show_main_menu_frame(self):
|
|
|
|
|
"""
|
|
|
|
|
显示主菜单界面
|
|
|
|
|
"""
|
|
|
|
|
# 清除之前的内容
|
|
|
|
|
for widget in self.main_menu_frame.winfo_children():
|
|
|
|
|
widget.destroy()
|
|
|
|
|
|
|
|
|
|
# 创建主菜单界面
|
|
|
|
|
main_frame = tk.Frame(self.main_menu_frame, bg="#ffffff", relief=tk.RAISED, bd=2)
|
|
|
|
|
main_frame.pack(pady=30, padx=50, fill="both", expand=True)
|
|
|
|
|
|
|
|
|
|
title_frame = tk.Frame(main_frame, bg=self.primary_color)
|
|
|
|
|
title_frame.pack(fill="x", pady=(0, 20))
|
|
|
|
|
tk.Label(title_frame, text="主菜单", font=self.title_font, bg=self.primary_color, fg="white").pack(pady=20)
|
|
|
|
|
|
|
|
|
|
user_email = self.user_manager.current_user.email if self.user_manager.current_user else "未知用户"
|
|
|
|
|
tk.Label(main_frame, text=f"欢迎, {user_email}!", font=self.header_font, bg="#ffffff").pack(pady=10)
|
|
|
|
|
|
|
|
|
|
button_frame = tk.Frame(main_frame, bg="#ffffff")
|
|
|
|
|
button_frame.pack(pady=20)
|
|
|
|
|
|
|
|
|
|
tk.Button(button_frame, text="小学题目", command=lambda: self.show_quiz_setup_frame("elementary"),
|
|
|
|
|
width=20, height=2, bg="#4CAF50", fg="white", font=self.button_font, relief=tk.FLAT, bd=0).pack(pady=10)
|
|
|
|
|
tk.Button(button_frame, text="初中题目", command=lambda: self.show_quiz_setup_frame("middle"),
|
|
|
|
|
width=20, height=2, bg="#2196F3", fg="white", font=self.button_font, relief=tk.FLAT, bd=0).pack(pady=10)
|
|
|
|
|
tk.Button(button_frame, text="高中题目", command=lambda: self.show_quiz_setup_frame("high"),
|
|
|
|
|
width=20, height=2, bg="#FF9800", fg="white", font=self.button_font, relief=tk.FLAT, bd=0).pack(pady=10)
|
|
|
|
|
|
|
|
|
|
tk.Button(button_frame, text="修改密码", command=self.show_change_password_frame,
|
|
|
|
|
width=20, bg=self.secondary_color, fg="white", font=self.button_font, relief=tk.FLAT, bd=0, pady=5).pack(pady=10)
|
|
|
|
|
tk.Button(button_frame, text="退出登录", command=self.logout, width=20, bg=self.danger_color, fg="white",
|
|
|
|
|
font=self.button_font, relief=tk.FLAT, bd=0, pady=5).pack(pady=5)
|
|
|
|
|
|
|
|
|
|
self.show_frame(self.main_menu_frame)
|
|
|
|
|
|
|
|
|
|
def show_quiz_setup_frame(self, level: str):
|
|
|
|
|
"""
|
|
|
|
|
显示测验设置界面
|
|
|
|
|
|
|
|
|
|
@param level: 题目难度
|
|
|
|
|
"""
|
|
|
|
|
self.current_level = level
|
|
|
|
|
|
|
|
|
|
# 清除之前的内容
|
|
|
|
|
for widget in self.quiz_setup_frame.winfo_children():
|
|
|
|
|
widget.destroy()
|
|
|
|
|
|
|
|
|
|
# 创建测验设置界面
|
|
|
|
|
main_frame = tk.Frame(self.quiz_setup_frame, bg="#ffffff", relief=tk.RAISED, bd=2)
|
|
|
|
|
main_frame.pack(pady=30, padx=50, fill="both", expand=True)
|
|
|
|
|
|
|
|
|
|
level_names = {"elementary": "小学", "middle": "初中", "high": "高中"}
|
|
|
|
|
level_colors = {"elementary": "#4CAF50", "middle": "#2196F3", "high": "#FF9800"}
|
|
|
|
|
|
|
|
|
|
title_frame = tk.Frame(main_frame, bg=level_colors[level])
|
|
|
|
|
title_frame.pack(fill="x", pady=(0, 20))
|
|
|
|
|
tk.Label(title_frame, text=f"{level_names[level]}数学题目", font=self.title_font, bg=level_colors[level], fg="white").pack(pady=20)
|
|
|
|
|
|
|
|
|
|
form_frame = tk.Frame(main_frame, bg="#ffffff")
|
|
|
|
|
form_frame.pack(pady=20)
|
|
|
|
|
|
|
|
|
|
tk.Label(form_frame, text="请输入题目数量 (1-20):", font=self.normal_font, bg="#ffffff").pack(pady=10)
|
|
|
|
|
self.question_count_entry = tk.Entry(form_frame, width=20, font=self.normal_font, justify="center", relief=tk.FLAT, bd=5, bg="#f0f0f0")
|
|
|
|
|
self.question_count_entry.pack(pady=5)
|
|
|
|
|
self.question_count_entry.insert(0, "10") # 默认10题
|
|
|
|
|
|
|
|
|
|
button_frame = tk.Frame(main_frame, bg="#ffffff")
|
|
|
|
|
button_frame.pack(pady=20)
|
|
|
|
|
|
|
|
|
|
tk.Button(button_frame, text="开始答题", command=self.start_quiz, width=20, bg=self.success_color, fg="white",
|
|
|
|
|
font=self.button_font, relief=tk.FLAT, bd=0, padx=10, pady=5).pack(pady=10)
|
|
|
|
|
tk.Button(button_frame, text="返回主菜单", command=self.show_main_menu_frame, width=20, bg="#cccccc", fg=self.dark_text,
|
|
|
|
|
font=self.button_font, relief=tk.FLAT, bd=0, padx=10, pady=5).pack(pady=5)
|
|
|
|
|
|
|
|
|
|
self.show_frame(self.quiz_setup_frame)
|
|
|
|
|
|
|
|
|
|
def start_quiz(self):
|
|
|
|
|
"""
|
|
|
|
|
开始测验
|
|
|
|
|
"""
|
|
|
|
|
try:
|
|
|
|
|
count = int(self.question_count_entry.get())
|
|
|
|
|
if not (1 <= count <= 20):
|
|
|
|
|
messagebox.showerror("错误", "题目数量必须在1-20之间")
|
|
|
|
|
return
|
|
|
|
|
except ValueError:
|
|
|
|
|
messagebox.showerror("错误", "请输入有效的数字")
|
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
self.question_count = count
|
|
|
|
|
|
|
|
|
|
# 生成题目
|
|
|
|
|
try:
|
|
|
|
|
questions = self.question_bank.generate_questions(self.current_level, self.question_count)
|
|
|
|
|
self.current_quiz = Quiz(questions)
|
|
|
|
|
self.show_quiz_frame()
|
|
|
|
|
except Exception as e:
|
|
|
|
|
messagebox.showerror("错误", f"生成题目时出错: {str(e)}")
|
|
|
|
|
|
|
|
|
|
def show_quiz_frame(self):
|
|
|
|
|
"""
|
|
|
|
|
显示答题界面
|
|
|
|
|
"""
|
|
|
|
|
if not self.current_quiz:
|
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
# 清除之前的内容
|
|
|
|
|
for widget in self.quiz_frame.winfo_children():
|
|
|
|
|
widget.destroy()
|
|
|
|
|
|
|
|
|
|
# 创建答题界面
|
|
|
|
|
current_question = self.current_quiz.get_current_question()
|
|
|
|
|
if not current_question:
|
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
main_frame = tk.Frame(self.quiz_frame, bg="#ffffff", relief=tk.RAISED, bd=2)
|
|
|
|
|
main_frame.pack(pady=20, padx=30, fill="both", expand=True)
|
|
|
|
|
|
|
|
|
|
# 显示题目进度
|
|
|
|
|
progress = f"题目 {self.current_quiz.current_question_index + 1}/{len(self.current_quiz.questions)}"
|
|
|
|
|
progress_frame = tk.Frame(main_frame, bg=self.primary_color)
|
|
|
|
|
progress_frame.pack(fill="x", pady=(0, 20))
|
|
|
|
|
tk.Label(progress_frame, text=progress, font=self.header_font, bg=self.primary_color, fg="white").pack(pady=10)
|
|
|
|
|
|
|
|
|
|
# 显示题目
|
|
|
|
|
question_frame = tk.Frame(main_frame, bg="#ffffff")
|
|
|
|
|
question_frame.pack(pady=10)
|
|
|
|
|
|
|
|
|
|
tk.Label(question_frame, text="题目:", font=self.header_font, bg="#ffffff").pack(pady=(10, 5))
|
|
|
|
|
question_text = str(current_question)
|
|
|
|
|
tk.Label(question_frame, text=question_text, font=("Arial", 16, "bold"), bg="#ffffff", wraplength=500).pack(pady=10)
|
|
|
|
|
|
|
|
|
|
# 计算选项
|
|
|
|
|
options = self.generate_options(current_question.answer)
|
|
|
|
|
|
|
|
|
|
# 显示选项
|
|
|
|
|
tk.Label(main_frame, text="请选择答案:", font=self.normal_font, bg="#ffffff").pack(pady=(20, 10))
|
|
|
|
|
|
|
|
|
|
self.answer_var = tk.StringVar()
|
|
|
|
|
self.answer_var.set(" ") # 明确设置初始值为空字符串,确保不选中任何选项
|
|
|
|
|
|
|
|
|
|
options_frame = tk.Frame(main_frame, bg="#ffffff")
|
|
|
|
|
options_frame.pack(pady=10)
|
|
|
|
|
|
|
|
|
|
for i, option in enumerate(options):
|
|
|
|
|
tk.Radiobutton(options_frame, text=f"{['A', 'B', 'C', 'D'][i]}. {option}",
|
|
|
|
|
variable=self.answer_var, value=str(option), font=self.normal_font,
|
|
|
|
|
bg="#ffffff", selectcolor="#e0e0e0", activebackground="#f0f0f0").pack(anchor="w", padx=50, pady=5)
|
|
|
|
|
|
|
|
|
|
# 按钮框架
|
|
|
|
|
button_frame = tk.Frame(main_frame, bg="#ffffff")
|
|
|
|
|
button_frame.pack(pady=20)
|
|
|
|
|
|
|
|
|
|
if self.current_quiz.current_question_index > 0:
|
|
|
|
|
tk.Button(button_frame, text="上一题", command=self.previous_question, bg="#cccccc", fg=self.dark_text,
|
|
|
|
|
font=self.button_font, relief=tk.FLAT, bd=0, padx=10, pady=5).pack(side="left", padx=10)
|
|
|
|
|
|
|
|
|
|
tk.Button(button_frame, text="提交答案", command=self.submit_answer, bg=self.success_color, fg="white",
|
|
|
|
|
font=self.button_font, relief=tk.FLAT, bd=0, padx=10, pady=5).pack(side="left", padx=10)
|
|
|
|
|
|
|
|
|
|
if self.current_quiz.current_question_index < len(self.current_quiz.questions) - 1:
|
|
|
|
|
tk.Button(button_frame, text="下一题", command=self.next_question, bg=self.primary_color, fg="white",
|
|
|
|
|
font=self.button_font, relief=tk.FLAT, bd=0, padx=10, pady=5).pack(side="left", padx=10)
|
|
|
|
|
|
|
|
|
|
tk.Button(main_frame, text="返回主菜单", command=self.show_main_menu_frame, width=15, bg=self.danger_color, fg="white",
|
|
|
|
|
font=self.button_font, relief=tk.FLAT, bd=0, padx=10, pady=5).pack(pady=10)
|
|
|
|
|
|
|
|
|
|
self.show_frame(self.quiz_frame)
|
|
|
|
|
|
|
|
|
|
def generate_options(self, correct_answer) -> List[float]:
|
|
|
|
|
"""
|
|
|
|
|
为题目生成选项
|
|
|
|
|
|
|
|
|
|
@param correct_answer: 正确答案
|
|
|
|
|
@return: 选项列表
|
|
|
|
|
"""
|
|
|
|
|
# 生成4个选项,其中一个是正确答案
|
|
|
|
|
options = {correct_answer}
|
|
|
|
|
|
|
|
|
|
# 添加一些干扰项
|
|
|
|
|
if isinstance(correct_answer, int):
|
|
|
|
|
while len(options) < 4:
|
|
|
|
|
offset = random.randint(-10, 10)
|
|
|
|
|
if offset != 0:
|
|
|
|
|
options.add(correct_answer + offset)
|
|
|
|
|
else:
|
|
|
|
|
# 浮点数情况
|
|
|
|
|
while len(options) < 4:
|
|
|
|
|
offset = random.uniform(-10, 10)
|
|
|
|
|
if abs(offset) > 0.1: # 避免太接近正确答案
|
|
|
|
|
options.add(round(correct_answer + offset, 2))
|
|
|
|
|
|
|
|
|
|
# 如果选项不足4个,补充一些随机数
|
|
|
|
|
while len(options) < 4:
|
|
|
|
|
options.add(round(random.uniform(correct_answer - 20, correct_answer + 20), 2))
|
|
|
|
|
|
|
|
|
|
options_list = list(options)
|
|
|
|
|
random.shuffle(options_list)
|
|
|
|
|
return options_list[:4]
|
|
|
|
|
|
|
|
|
|
def submit_answer(self):
|
|
|
|
|
"""
|
|
|
|
|
提交答案
|
|
|
|
|
"""
|
|
|
|
|
if not self.current_quiz:
|
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
answer_str = self.answer_var.get()
|
|
|
|
|
if not answer_str:
|
|
|
|
|
messagebox.showerror("错误", "请选择一个答案")
|
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
try:
|
|
|
|
|
answer = float(answer_str)
|
|
|
|
|
self.current_quiz.answer_question(answer)
|
|
|
|
|
|
|
|
|
|
# 如果是最后一题,显示结果
|
|
|
|
|
if self.current_quiz.is_finished():
|
|
|
|
|
self.show_result_frame()
|
|
|
|
|
else:
|
|
|
|
|
messagebox.showinfo("提示", "答案已提交")
|
|
|
|
|
except ValueError:
|
|
|
|
|
messagebox.showerror("错误", "请选择有效答案")
|
|
|
|
|
|
|
|
|
|
def next_question(self):
|
|
|
|
|
"""
|
|
|
|
|
下一题
|
|
|
|
|
"""
|
|
|
|
|
if not self.current_quiz:
|
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
# 保存当前答案(如果有选择)
|
|
|
|
|
answer_str = self.answer_var.get()
|
|
|
|
|
if answer_str:
|
|
|
|
|
try:
|
|
|
|
|
answer = float(answer_str)
|
|
|
|
|
self.current_quiz.answer_question(answer)
|
|
|
|
|
except ValueError:
|
|
|
|
|
pass # 如果答案无效,保持为None
|
|
|
|
|
|
|
|
|
|
if self.current_quiz.next_question():
|
|
|
|
|
self.show_quiz_frame()
|
|
|
|
|
else:
|
|
|
|
|
# 已经是最后一题
|
|
|
|
|
if self.current_quiz.answers[self.current_quiz.current_question_index] is not None:
|
|
|
|
|
# 如果最后一题已答题,显示结果
|
|
|
|
|
self.show_result_frame()
|
|
|
|
|
else:
|
|
|
|
|
messagebox.showinfo("提示", "已经是最后一题")
|
|
|
|
|
|
|
|
|
|
def previous_question(self):
|
|
|
|
|
"""
|
|
|
|
|
上一题
|
|
|
|
|
"""
|
|
|
|
|
if not self.current_quiz:
|
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
# 保存当前答案(如果有选择)
|
|
|
|
|
answer_str = self.answer_var.get()
|
|
|
|
|
if answer_str:
|
|
|
|
|
try:
|
|
|
|
|
answer = float(answer_str)
|
|
|
|
|
self.current_quiz.answer_question(answer)
|
|
|
|
|
except ValueError:
|
|
|
|
|
pass # 如果答案无效,保持为None
|
|
|
|
|
|
|
|
|
|
if self.current_quiz.previous_question():
|
|
|
|
|
self.show_quiz_frame()
|
|
|
|
|
|
|
|
|
|
def show_result_frame(self):
|
|
|
|
|
"""
|
|
|
|
|
显示结果界面
|
|
|
|
|
"""
|
|
|
|
|
if not self.current_quiz:
|
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
# 清除之前的内容
|
|
|
|
|
for widget in self.result_frame.winfo_children():
|
|
|
|
|
widget.destroy()
|
|
|
|
|
|
|
|
|
|
# 计算得分
|
|
|
|
|
score = self.current_quiz.calculate_score()
|
|
|
|
|
|
|
|
|
|
# 创建结果界面
|
|
|
|
|
main_frame = tk.Frame(self.result_frame, bg="#ffffff", relief=tk.RAISED, bd=2)
|
|
|
|
|
main_frame.pack(pady=30, padx=50, fill="both", expand=True)
|
|
|
|
|
|
|
|
|
|
title_frame = tk.Frame(main_frame, bg=self.primary_color)
|
|
|
|
|
title_frame.pack(fill="x", pady=(0, 20))
|
|
|
|
|
tk.Label(title_frame, text="测验结果", font=self.title_font, bg=self.primary_color, fg="white").pack(pady=20)
|
|
|
|
|
|
|
|
|
|
result_frame = tk.Frame(main_frame, bg="#ffffff")
|
|
|
|
|
result_frame.pack(pady=20)
|
|
|
|
|
|
|
|
|
|
# 根据得分显示不同颜色的分数
|
|
|
|
|
score_color = self.danger_color if score < 60 else self.warning_color if score < 80 else self.success_color
|
|
|
|
|
|
|
|
|
|
tk.Label(result_frame, text=f"您的得分: {score:.1f}%", font=("Arial", 20, "bold"), fg=score_color, bg="#ffffff").pack(pady=10)
|
|
|
|
|
|
|
|
|
|
# 根据得分显示评语
|
|
|
|
|
if score >= 90:
|
|
|
|
|
comment = "优秀! 继续保持!"
|
|
|
|
|
comment_color = self.success_color
|
|
|
|
|
elif score >= 80:
|
|
|
|
|
comment = "良好! 还可以做得更好!"
|
|
|
|
|
comment_color = self.success_color
|
|
|
|
|
elif score >= 60:
|
|
|
|
|
comment = "及格了,需要继续努力!"
|
|
|
|
|
comment_color = self.warning_color
|
|
|
|
|
else:
|
|
|
|
|
comment = "需要加强练习哦!"
|
|
|
|
|
comment_color = self.danger_color
|
|
|
|
|
|
|
|
|
|
tk.Label(result_frame, text=comment, font=self.header_font, fg=comment_color, bg="#ffffff").pack(pady=10)
|
|
|
|
|
|
|
|
|
|
# 显示答题详情
|
|
|
|
|
correct_count = sum(1 for q, a in zip(self.current_quiz.questions, self.current_quiz.answers)
|
|
|
|
|
if a is not None and abs(q.answer - a) < 1e-6)
|
|
|
|
|
total_count = len(self.current_quiz.questions)
|
|
|
|
|
tk.Label(result_frame, text=f"答对: {correct_count}/{total_count}", font=self.normal_font, bg="#ffffff").pack(pady=5)
|
|
|
|
|
|
|
|
|
|
# 按钮
|
|
|
|
|
button_frame = tk.Frame(main_frame, bg="#ffffff")
|
|
|
|
|
button_frame.pack(pady=30)
|
|
|
|
|
|
|
|
|
|
level_names = {"elementary": "小学", "middle": "初中", "high": "高中"}
|
|
|
|
|
tk.Button(button_frame, text=f"继续{level_names[self.current_level]}题目",
|
|
|
|
|
command=lambda: self.show_quiz_setup_frame(self.current_level), width=20, bg=self.primary_color, fg="white",
|
|
|
|
|
font=self.button_font, relief=tk.FLAT, bd=0, padx=10, pady=5).pack(side="left", padx=10)
|
|
|
|
|
|
|
|
|
|
tk.Button(button_frame, text="返回主菜单", command=self.show_main_menu_frame, width=15, bg="#cccccc", fg=self.dark_text,
|
|
|
|
|
font=self.button_font, relief=tk.FLAT, bd=0, padx=10, pady=5).pack(side="left", padx=10)
|
|
|
|
|
|
|
|
|
|
self.show_frame(self.result_frame)
|
|
|
|
|
|
|
|
|
|
def show_change_password_frame(self):
|
|
|
|
|
"""
|
|
|
|
|
显示修改密码界面
|
|
|
|
|
"""
|
|
|
|
|
# 清除之前的内容
|
|
|
|
|
for widget in self.change_password_frame.winfo_children():
|
|
|
|
|
widget.destroy()
|
|
|
|
|
|
|
|
|
|
# 创建修改密码界面
|
|
|
|
|
main_frame = tk.Frame(self.change_password_frame, bg="#ffffff", relief=tk.RAISED, bd=2)
|
|
|
|
|
main_frame.pack(pady=30, padx=50, fill="both", expand=True)
|
|
|
|
|
|
|
|
|
|
title_frame = tk.Frame(main_frame, bg=self.primary_color)
|
|
|
|
|
title_frame.pack(fill="x", pady=(0, 20))
|
|
|
|
|
tk.Label(title_frame, text="修改密码", font=self.title_font, bg=self.primary_color, fg="white").pack(pady=20)
|
|
|
|
|
|
|
|
|
|
form_frame = tk.Frame(main_frame, bg="#ffffff")
|
|
|
|
|
form_frame.pack(pady=10)
|
|
|
|
|
|
|
|
|
|
tk.Label(form_frame, text="原密码:", font=self.normal_font, bg="#ffffff").pack(pady=5, anchor="w")
|
|
|
|
|
self.old_password_entry = tk.Entry(form_frame, width=30, font=self.normal_font, show="*", relief=tk.FLAT, bd=5, bg="#f0f0f0")
|
|
|
|
|
self.old_password_entry.pack(pady=5)
|
|
|
|
|
|
|
|
|
|
tk.Label(form_frame, text="新密码:", font=self.normal_font, bg="#ffffff", fg=self.primary_color).pack(pady=(10, 5), anchor="w")
|
|
|
|
|
tk.Label(form_frame, text="(6-10位,必须包含大小写字母和数字)", font=("Arial", 10), bg="#ffffff", fg="gray").pack(pady=5, anchor="w")
|
|
|
|
|
self.new_password_entry = tk.Entry(form_frame, width=30, font=self.normal_font, show="*", relief=tk.FLAT, bd=5, bg="#f0f0f0")
|
|
|
|
|
self.new_password_entry.pack(pady=5)
|
|
|
|
|
|
|
|
|
|
tk.Label(form_frame, text="确认新密码:", font=self.normal_font, bg="#ffffff").pack(pady=5, anchor="w")
|
|
|
|
|
self.confirm_new_password_entry = tk.Entry(form_frame, width=30, font=self.normal_font, show="*", relief=tk.FLAT, bd=5, bg="#f0f0f0")
|
|
|
|
|
self.confirm_new_password_entry.pack(pady=5)
|
|
|
|
|
|
|
|
|
|
button_frame = tk.Frame(main_frame, bg="#ffffff")
|
|
|
|
|
button_frame.pack(pady=20)
|
|
|
|
|
|
|
|
|
|
tk.Button(button_frame, text="修改密码", command=self.change_password, width=20, bg=self.success_color, fg="white",
|
|
|
|
|
font=self.button_font, relief=tk.FLAT, bd=0, padx=10, pady=5).pack(pady=10)
|
|
|
|
|
tk.Button(button_frame, text="返回主菜单", command=self.show_main_menu_frame, width=20, bg="#cccccc", fg=self.dark_text,
|
|
|
|
|
font=self.button_font, relief=tk.FLAT, bd=0, padx=10, pady=5).pack(pady=5)
|
|
|
|
|
|
|
|
|
|
self.show_frame(self.change_password_frame)
|
|
|
|
|
|
|
|
|
|
def change_password(self):
|
|
|
|
|
"""
|
|
|
|
|
修改密码
|
|
|
|
|
"""
|
|
|
|
|
old_password = self.old_password_entry.get()
|
|
|
|
|
new_password = self.new_password_entry.get()
|
|
|
|
|
confirm_new_password = self.confirm_new_password_entry.get()
|
|
|
|
|
|
|
|
|
|
if not old_password or not new_password or not confirm_new_password:
|
|
|
|
|
messagebox.showerror("错误", "请填写所有字段")
|
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
if new_password != confirm_new_password:
|
|
|
|
|
messagebox.showerror("错误", "新密码和确认密码不一致")
|
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
if self.user_manager.change_password(old_password, new_password):
|
|
|
|
|
messagebox.showinfo("成功", "密码修改成功")
|
|
|
|
|
self.show_main_menu_frame()
|
|
|
|
|
# 错误信息在user_manager.change_password中已经显示
|
|
|
|
|
|
|
|
|
|
def logout(self):
|
|
|
|
|
"""
|
|
|
|
|
退出登录
|
|
|
|
|
"""
|
|
|
|
|
self.user_manager.logout()
|
|
|
|
|
self.show_login_frame()
|
|
|
|
|
|
|
|
|
|
def show_delete_account_frame(self):
|
|
|
|
|
"""
|
|
|
|
|
显示注销账户界面
|
|
|
|
|
"""
|
|
|
|
|
# 清除之前的内容
|
|
|
|
|
for widget in self.delete_account_frame.winfo_children():
|
|
|
|
|
widget.destroy()
|
|
|
|
|
|
|
|
|
|
# 创建注销账户界面
|
|
|
|
|
main_frame = tk.Frame(self.delete_account_frame, bg="#ffffff", relief=tk.RAISED, bd=2)
|
|
|
|
|
main_frame.pack(pady=30, padx=50, fill="both", expand=True)
|
|
|
|
|
|
|
|
|
|
title_frame = tk.Frame(main_frame, bg=self.danger_color)
|
|
|
|
|
title_frame.pack(fill="x", pady=(0, 20))
|
|
|
|
|
tk.Label(title_frame, text="注销账户", font=self.title_font, bg=self.danger_color, fg="white").pack(pady=20)
|
|
|
|
|
|
|
|
|
|
warning_frame = tk.Frame(main_frame, bg="#ffffff")
|
|
|
|
|
warning_frame.pack(pady=10)
|
|
|
|
|
|
|
|
|
|
tk.Label(warning_frame, text="警告:此操作将永久删除您的账户和所有数据!", font=self.normal_font, fg=self.danger_color, bg="#ffffff").pack(pady=5)
|
|
|
|
|
tk.Label(warning_frame, text="请确认您的邮箱和密码:", font=self.normal_font, fg=self.danger_color, bg="#ffffff").pack(pady=5)
|
|
|
|
|
|
|
|
|
|
form_frame = tk.Frame(main_frame, bg="#ffffff")
|
|
|
|
|
form_frame.pack(pady=10)
|
|
|
|
|
|
|
|
|
|
tk.Label(form_frame, text="邮箱:", font=self.normal_font, bg="#ffffff").pack(pady=10, anchor="w")
|
|
|
|
|
self.delete_email_entry = tk.Entry(form_frame, width=30, font=self.normal_font, relief=tk.FLAT, bd=5, bg="#f0f0f0")
|
|
|
|
|
self.delete_email_entry.pack(pady=5)
|
|
|
|
|
|
|
|
|
|
tk.Label(form_frame, text="密码:", font=self.normal_font, bg="#ffffff").pack(pady=5, anchor="w")
|
|
|
|
|
self.delete_password_entry = tk.Entry(form_frame, width=30, font=self.normal_font, show="*", relief=tk.FLAT, bd=5, bg="#f0f0f0")
|
|
|
|
|
self.delete_password_entry.pack(pady=5)
|
|
|
|
|
|
|
|
|
|
# 按钮框架
|
|
|
|
|
button_frame = tk.Frame(main_frame, bg="#ffffff")
|
|
|
|
|
button_frame.pack(pady=20)
|
|
|
|
|
|
|
|
|
|
tk.Button(button_frame, text="确认注销", command=self.confirm_delete_account,
|
|
|
|
|
width=15, bg=self.danger_color, fg="white", font=self.button_font, relief=tk.FLAT, bd=0, padx=10, pady=5).pack(side="left", padx=10)
|
|
|
|
|
tk.Button(button_frame, text="取消", command=self.show_login_frame,
|
|
|
|
|
width=15, bg="#cccccc", fg=self.dark_text, font=self.button_font, relief=tk.FLAT, bd=0, padx=10, pady=5).pack(side="left", padx=10)
|
|
|
|
|
|
|
|
|
|
self.show_frame(self.delete_account_frame)
|
|
|
|
|
|
|
|
|
|
def confirm_delete_account(self):
|
|
|
|
|
"""
|
|
|
|
|
确认并执行账户删除操作
|
|
|
|
|
"""
|
|
|
|
|
email = self.delete_email_entry.get().strip()
|
|
|
|
|
password = self.delete_password_entry.get()
|
|
|
|
|
|
|
|
|
|
if not email or not password:
|
|
|
|
|
messagebox.showerror("错误", "请输入邮箱和密码")
|
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
# 确认操作
|
|
|
|
|
if messagebox.askyesno("确认注销", "确定要注销账户吗?此操作无法撤销!"):
|
|
|
|
|
if self.user_manager.delete_account(email, password):
|
|
|
|
|
messagebox.showinfo("成功", "账户已注销,您可以使用该邮箱重新注册")
|
|
|
|
|
self.show_login_frame()
|
|
|
|
|
# 错误信息在user_manager.delete_account中已经显示
|
|
|
|
|
|
|
|
|
|
def delete_account(self):
|
|
|
|
|
"""
|
|
|
|
|
注销账户(从主菜单调用的旧方法,保持兼容性)
|
|
|
|
|
"""
|
|
|
|
|
self.show_delete_account_frame()
|