|
|
"""
|
|
|
数学学习软件 - GUI界面模块
|
|
|
使用Tkinter实现桌面应用界面
|
|
|
"""
|
|
|
import tkinter as tk
|
|
|
from tkinter import ttk, messagebox, simpledialog
|
|
|
from typing import List, Dict, Optional
|
|
|
from data_manager import DataManager, QuestionGenerator, ScoreCalculator
|
|
|
from email_config_gui import EmailConfigWindow
|
|
|
|
|
|
class MathLearningApp:
|
|
|
"""数学学习软件主应用类"""
|
|
|
|
|
|
def __init__(self):
|
|
|
self.root = tk.Tk()
|
|
|
self.root.title("数学学习软件")
|
|
|
self.root.geometry("800x600")
|
|
|
self.root.resizable(False, False)
|
|
|
|
|
|
# 初始化数据管理器
|
|
|
self.data_manager = DataManager()
|
|
|
self.question_generator = QuestionGenerator()
|
|
|
self.score_calculator = ScoreCalculator()
|
|
|
|
|
|
# 当前测试相关变量
|
|
|
self.current_questions = []
|
|
|
self.current_question_index = 0
|
|
|
self.user_answers = []
|
|
|
self.selected_level = ""
|
|
|
|
|
|
# 创建主框架
|
|
|
self.main_frame = ttk.Frame(self.root, padding="20")
|
|
|
self.main_frame.grid(row=0, column=0, sticky=(tk.W, tk.E, tk.N, tk.S))
|
|
|
|
|
|
# 配置网格权重
|
|
|
self.root.columnconfigure(0, weight=1)
|
|
|
self.root.rowconfigure(0, weight=1)
|
|
|
self.main_frame.columnconfigure(0, weight=1)
|
|
|
|
|
|
# 显示欢迎界面
|
|
|
self.show_welcome_screen()
|
|
|
|
|
|
def clear_frame(self):
|
|
|
"""清空主框架"""
|
|
|
for widget in self.main_frame.winfo_children():
|
|
|
widget.destroy()
|
|
|
|
|
|
def show_welcome_screen(self):
|
|
|
"""显示欢迎界面"""
|
|
|
self.clear_frame()
|
|
|
|
|
|
# 标题
|
|
|
title_label = ttk.Label(self.main_frame, text="数学学习软件",
|
|
|
font=("Arial", 24, "bold"))
|
|
|
title_label.grid(row=0, column=0, pady=30)
|
|
|
|
|
|
# 按钮框架
|
|
|
button_frame = ttk.Frame(self.main_frame)
|
|
|
button_frame.grid(row=1, column=0, pady=20)
|
|
|
|
|
|
# 注册按钮
|
|
|
register_btn = ttk.Button(button_frame, text="用户注册",
|
|
|
command=self.show_register_screen, width=15)
|
|
|
register_btn.grid(row=0, column=0, padx=10, pady=10)
|
|
|
|
|
|
# 登录按钮
|
|
|
login_btn = ttk.Button(button_frame, text="用户登录",
|
|
|
command=self.show_login_screen, width=15)
|
|
|
login_btn.grid(row=0, column=1, padx=10, pady=10)
|
|
|
|
|
|
# 邮箱配置按钮
|
|
|
config_btn = ttk.Button(button_frame, text="邮箱配置",
|
|
|
command=self.show_email_config, width=15)
|
|
|
config_btn.grid(row=1, column=0, columnspan=2, pady=5)
|
|
|
|
|
|
# 退出按钮
|
|
|
exit_btn = ttk.Button(button_frame, text="退出程序",
|
|
|
command=self.root.quit, width=15)
|
|
|
exit_btn.grid(row=2, column=0, columnspan=2, pady=10)
|
|
|
|
|
|
def show_register_screen(self):
|
|
|
"""显示注册界面"""
|
|
|
self.clear_frame()
|
|
|
|
|
|
# 标题
|
|
|
title_label = ttk.Label(self.main_frame, text="用户注册",
|
|
|
font=("Arial", 18, "bold"))
|
|
|
title_label.grid(row=0, column=0, pady=20)
|
|
|
|
|
|
# 输入框架
|
|
|
input_frame = ttk.Frame(self.main_frame)
|
|
|
input_frame.grid(row=1, column=0, pady=10)
|
|
|
|
|
|
# 用户名输入
|
|
|
ttk.Label(input_frame, text="用户名:").grid(row=0, column=0, padx=5, pady=5)
|
|
|
self.username_entry = ttk.Entry(input_frame, width=30)
|
|
|
self.username_entry.grid(row=0, column=1, padx=5, pady=5)
|
|
|
|
|
|
# 邮箱输入
|
|
|
ttk.Label(input_frame, text="邮箱地址:").grid(row=1, column=0, padx=5, pady=5)
|
|
|
self.email_entry = ttk.Entry(input_frame, width=30)
|
|
|
self.email_entry.grid(row=1, column=1, padx=5, pady=5)
|
|
|
|
|
|
# 提示信息
|
|
|
info_label = ttk.Label(self.main_frame,
|
|
|
text="注册码将发送到您的邮箱,请确保邮箱地址正确",
|
|
|
font=("Arial", 10))
|
|
|
info_label.grid(row=2, column=0, pady=10)
|
|
|
|
|
|
# 注册按钮
|
|
|
register_btn = ttk.Button(self.main_frame, text="发送注册码",
|
|
|
command=self.handle_register)
|
|
|
register_btn.grid(row=3, column=0, pady=20)
|
|
|
|
|
|
# 返回按钮
|
|
|
back_btn = ttk.Button(self.main_frame, text="返回",
|
|
|
command=self.show_welcome_screen)
|
|
|
back_btn.grid(row=4, column=0, pady=10)
|
|
|
|
|
|
def handle_register(self):
|
|
|
"""处理用户注册"""
|
|
|
username = self.username_entry.get().strip()
|
|
|
email = self.email_entry.get().strip()
|
|
|
|
|
|
if not username:
|
|
|
messagebox.showerror("错误", "请输入用户名")
|
|
|
return
|
|
|
|
|
|
if not email:
|
|
|
messagebox.showerror("错误", "请输入邮箱地址")
|
|
|
return
|
|
|
|
|
|
# 用户名格式验证
|
|
|
if len(username) < 2 or len(username) > 20:
|
|
|
messagebox.showerror("错误", "用户名长度应在2-20个字符之间")
|
|
|
return
|
|
|
|
|
|
# 简单的邮箱格式验证
|
|
|
if "@" not in email or "." not in email:
|
|
|
messagebox.showerror("错误", "请输入有效的邮箱地址")
|
|
|
return
|
|
|
|
|
|
try:
|
|
|
# 显示发送中的提示
|
|
|
messagebox.showinfo("发送中", "正在发送验证码到您的邮箱,请稍候...")
|
|
|
|
|
|
success = self.data_manager.register_user(email, username)
|
|
|
if success:
|
|
|
messagebox.showinfo("发送成功",
|
|
|
f"验证码已发送到 {email}\n请查收邮件并输入验证码")
|
|
|
self.show_verification_screen(email)
|
|
|
else:
|
|
|
messagebox.showerror("发送失败", "验证码发送失败,请稍后重试")
|
|
|
except ValueError as e:
|
|
|
messagebox.showerror("注册失败", str(e))
|
|
|
|
|
|
def show_verification_screen(self, email: str):
|
|
|
"""显示验证码输入界面"""
|
|
|
self.clear_frame()
|
|
|
|
|
|
# 标题
|
|
|
title_label = ttk.Label(self.main_frame, text="验证注册码",
|
|
|
font=("Arial", 18, "bold"))
|
|
|
title_label.grid(row=0, column=0, pady=20)
|
|
|
|
|
|
# 提示信息
|
|
|
info_label = ttk.Label(self.main_frame, text=f"验证码已发送到 {email}")
|
|
|
info_label.grid(row=1, column=0, pady=5)
|
|
|
|
|
|
info_label2 = ttk.Label(self.main_frame, text="请查收邮件并输入6位数字验证码",
|
|
|
font=("Arial", 10))
|
|
|
info_label2.grid(row=2, column=0, pady=5)
|
|
|
|
|
|
# 验证码输入
|
|
|
code_frame = ttk.Frame(self.main_frame)
|
|
|
code_frame.grid(row=3, column=0, pady=10)
|
|
|
|
|
|
ttk.Label(code_frame, text="注册码:").grid(row=0, column=0, padx=5)
|
|
|
self.code_entry = ttk.Entry(code_frame, width=20)
|
|
|
self.code_entry.grid(row=0, column=1, padx=5)
|
|
|
|
|
|
# 验证按钮
|
|
|
verify_btn = ttk.Button(self.main_frame, text="验证",
|
|
|
command=lambda: self.handle_verification(email))
|
|
|
verify_btn.grid(row=4, column=0, pady=20)
|
|
|
|
|
|
# 返回按钮
|
|
|
back_btn = ttk.Button(self.main_frame, text="返回",
|
|
|
command=self.show_register_screen)
|
|
|
back_btn.grid(row=5, column=0, pady=10)
|
|
|
|
|
|
def handle_verification(self, email: str):
|
|
|
"""处理验证码验证"""
|
|
|
code = self.code_entry.get().strip()
|
|
|
|
|
|
if not code:
|
|
|
messagebox.showerror("错误", "请输入注册码")
|
|
|
return
|
|
|
|
|
|
if self.data_manager.verify_registration(email, code):
|
|
|
messagebox.showinfo("验证成功", "注册码验证成功!")
|
|
|
self.show_password_setup_screen(email)
|
|
|
else:
|
|
|
messagebox.showerror("验证失败", "注册码错误,请重新输入")
|
|
|
|
|
|
def show_password_setup_screen(self, email: str):
|
|
|
"""显示密码设置界面"""
|
|
|
self.clear_frame()
|
|
|
|
|
|
# 标题
|
|
|
title_label = ttk.Label(self.main_frame, text="设置密码",
|
|
|
font=("Arial", 18, "bold"))
|
|
|
title_label.grid(row=0, column=0, pady=20)
|
|
|
|
|
|
# 密码要求说明
|
|
|
info_label = ttk.Label(self.main_frame,
|
|
|
text="密码要求:6-10位,必须包含大小写字母和数字")
|
|
|
info_label.grid(row=1, column=0, pady=10)
|
|
|
|
|
|
# 密码输入框架
|
|
|
password_frame = ttk.Frame(self.main_frame)
|
|
|
password_frame.grid(row=2, column=0, pady=20)
|
|
|
|
|
|
# 第一次密码输入
|
|
|
ttk.Label(password_frame, text="输入密码:").grid(row=0, column=0, padx=5, pady=5)
|
|
|
self.password1_entry = ttk.Entry(password_frame, show="*", width=20)
|
|
|
self.password1_entry.grid(row=0, column=1, padx=5, pady=5)
|
|
|
|
|
|
# 第二次密码输入
|
|
|
ttk.Label(password_frame, text="确认密码:").grid(row=1, column=0, padx=5, pady=5)
|
|
|
self.password2_entry = ttk.Entry(password_frame, show="*", width=20)
|
|
|
self.password2_entry.grid(row=1, column=1, padx=5, pady=5)
|
|
|
|
|
|
# 设置按钮
|
|
|
set_btn = ttk.Button(self.main_frame, text="设置密码",
|
|
|
command=lambda: self.handle_password_setup(email))
|
|
|
set_btn.grid(row=3, column=0, pady=20)
|
|
|
|
|
|
# 返回按钮
|
|
|
back_btn = ttk.Button(self.main_frame, text="返回",
|
|
|
command=self.show_welcome_screen)
|
|
|
back_btn.grid(row=4, column=0, pady=10)
|
|
|
|
|
|
def handle_password_setup(self, email: str):
|
|
|
"""处理密码设置"""
|
|
|
password1 = self.password1_entry.get()
|
|
|
password2 = self.password2_entry.get()
|
|
|
|
|
|
if not password1 or not password2:
|
|
|
messagebox.showerror("错误", "请输入密码")
|
|
|
return
|
|
|
|
|
|
if password1 != password2:
|
|
|
messagebox.showerror("错误", "两次输入的密码不一致")
|
|
|
return
|
|
|
|
|
|
if self.data_manager.set_password(email, password1):
|
|
|
messagebox.showinfo("成功", "密码设置成功!")
|
|
|
self.show_welcome_screen()
|
|
|
else:
|
|
|
messagebox.showerror("错误", "密码格式不符合要求")
|
|
|
|
|
|
def show_login_screen(self):
|
|
|
"""显示登录界面"""
|
|
|
self.clear_frame()
|
|
|
|
|
|
# 标题
|
|
|
title_label = ttk.Label(self.main_frame, text="用户登录",
|
|
|
font=("Arial", 18, "bold"))
|
|
|
title_label.grid(row=0, column=0, pady=20)
|
|
|
|
|
|
# 登录表单
|
|
|
login_frame = ttk.Frame(self.main_frame)
|
|
|
login_frame.grid(row=1, column=0, pady=20)
|
|
|
|
|
|
# 邮箱输入
|
|
|
ttk.Label(login_frame, text="邮箱:").grid(row=0, column=0, padx=5, pady=10)
|
|
|
self.login_email_entry = ttk.Entry(login_frame, width=25)
|
|
|
self.login_email_entry.grid(row=0, column=1, padx=5, pady=10)
|
|
|
|
|
|
# 密码输入
|
|
|
ttk.Label(login_frame, text="密码:").grid(row=1, column=0, padx=5, pady=10)
|
|
|
self.login_password_entry = ttk.Entry(login_frame, show="*", width=25)
|
|
|
self.login_password_entry.grid(row=1, column=1, padx=5, pady=10)
|
|
|
|
|
|
# 按钮框架
|
|
|
button_frame = ttk.Frame(self.main_frame)
|
|
|
button_frame.grid(row=2, column=0, pady=20)
|
|
|
|
|
|
# 登录按钮
|
|
|
login_btn = ttk.Button(button_frame, text="登录",
|
|
|
command=self.handle_login)
|
|
|
login_btn.grid(row=0, column=0, padx=10)
|
|
|
|
|
|
# 修改密码按钮
|
|
|
change_pwd_btn = ttk.Button(button_frame, text="修改密码",
|
|
|
command=self.show_change_password_screen)
|
|
|
change_pwd_btn.grid(row=0, column=1, padx=10)
|
|
|
|
|
|
# 返回按钮
|
|
|
back_btn = ttk.Button(self.main_frame, text="返回",
|
|
|
command=self.show_welcome_screen)
|
|
|
back_btn.grid(row=3, column=0, pady=10)
|
|
|
|
|
|
def handle_login(self):
|
|
|
"""处理用户登录"""
|
|
|
email = self.login_email_entry.get().strip()
|
|
|
password = self.login_password_entry.get()
|
|
|
|
|
|
if not email or not password:
|
|
|
messagebox.showerror("错误", "请输入邮箱和密码")
|
|
|
return
|
|
|
|
|
|
if self.data_manager.login(email, password):
|
|
|
messagebox.showinfo("成功", "登录成功!")
|
|
|
self.show_level_selection_screen()
|
|
|
else:
|
|
|
messagebox.showerror("错误", "邮箱或密码错误")
|
|
|
|
|
|
def show_change_password_screen(self):
|
|
|
"""显示修改密码界面"""
|
|
|
# 首先需要登录验证
|
|
|
email = self.login_email_entry.get().strip()
|
|
|
password = self.login_password_entry.get()
|
|
|
|
|
|
if not email or not password:
|
|
|
messagebox.showerror("错误", "请先输入邮箱和密码进行身份验证")
|
|
|
return
|
|
|
|
|
|
if not self.data_manager.login(email, password):
|
|
|
messagebox.showerror("错误", "邮箱或密码错误,无法修改密码")
|
|
|
return
|
|
|
|
|
|
self.clear_frame()
|
|
|
|
|
|
# 标题
|
|
|
title_label = ttk.Label(self.main_frame, text="修改密码",
|
|
|
font=("Arial", 18, "bold"))
|
|
|
title_label.grid(row=0, column=0, pady=20)
|
|
|
|
|
|
# 密码输入框架
|
|
|
password_frame = ttk.Frame(self.main_frame)
|
|
|
password_frame.grid(row=1, column=0, pady=20)
|
|
|
|
|
|
# 原密码
|
|
|
ttk.Label(password_frame, text="原密码:").grid(row=0, column=0, padx=5, pady=10)
|
|
|
self.old_password_entry = ttk.Entry(password_frame, show="*", width=20)
|
|
|
self.old_password_entry.grid(row=0, column=1, padx=5, pady=10)
|
|
|
|
|
|
# 新密码
|
|
|
ttk.Label(password_frame, text="新密码:").grid(row=1, column=0, padx=5, pady=10)
|
|
|
self.new_password1_entry = ttk.Entry(password_frame, show="*", width=20)
|
|
|
self.new_password1_entry.grid(row=1, column=1, padx=5, pady=10)
|
|
|
|
|
|
# 确认新密码
|
|
|
ttk.Label(password_frame, text="确认新密码:").grid(row=2, column=0, padx=5, pady=10)
|
|
|
self.new_password2_entry = ttk.Entry(password_frame, show="*", width=20)
|
|
|
self.new_password2_entry.grid(row=2, column=1, padx=5, pady=10)
|
|
|
|
|
|
# 修改按钮
|
|
|
change_btn = ttk.Button(self.main_frame, text="修改密码",
|
|
|
command=self.handle_change_password)
|
|
|
change_btn.grid(row=2, column=0, pady=20)
|
|
|
|
|
|
# 返回按钮
|
|
|
back_btn = ttk.Button(self.main_frame, text="返回",
|
|
|
command=self.show_login_screen)
|
|
|
back_btn.grid(row=3, column=0, pady=10)
|
|
|
|
|
|
def handle_change_password(self):
|
|
|
"""处理密码修改"""
|
|
|
old_password = self.old_password_entry.get()
|
|
|
new_password1 = self.new_password1_entry.get()
|
|
|
new_password2 = self.new_password2_entry.get()
|
|
|
|
|
|
if not all([old_password, new_password1, new_password2]):
|
|
|
messagebox.showerror("错误", "请填写所有密码字段")
|
|
|
return
|
|
|
|
|
|
if new_password1 != new_password2:
|
|
|
messagebox.showerror("错误", "两次输入的新密码不一致")
|
|
|
return
|
|
|
|
|
|
if self.data_manager.change_password(old_password, new_password1):
|
|
|
messagebox.showinfo("成功", "密码修改成功!")
|
|
|
self.show_login_screen()
|
|
|
else:
|
|
|
messagebox.showerror("错误", "原密码错误或新密码格式不符合要求")
|
|
|
|
|
|
def show_level_selection_screen(self):
|
|
|
"""显示学习阶段选择界面"""
|
|
|
self.clear_frame()
|
|
|
|
|
|
# 欢迎信息
|
|
|
username = self.data_manager.get_current_username()
|
|
|
welcome_label = ttk.Label(self.main_frame, text=f"欢迎,{username}!",
|
|
|
font=("Arial", 14))
|
|
|
welcome_label.grid(row=0, column=0, pady=10)
|
|
|
|
|
|
# 标题
|
|
|
title_label = ttk.Label(self.main_frame, text="选择学习阶段",
|
|
|
font=("Arial", 18, "bold"))
|
|
|
title_label.grid(row=1, column=0, pady=20)
|
|
|
|
|
|
# 阶段选择按钮
|
|
|
level_frame = ttk.Frame(self.main_frame)
|
|
|
level_frame.grid(row=2, column=0, pady=20)
|
|
|
|
|
|
levels = ["小学", "初中", "高中"]
|
|
|
for i, level in enumerate(levels):
|
|
|
btn = ttk.Button(level_frame, text=level, width=15,
|
|
|
command=lambda l=level: self.select_level(l))
|
|
|
btn.grid(row=i//2, column=i%2, padx=20, pady=15)
|
|
|
|
|
|
# 登出按钮
|
|
|
logout_btn = ttk.Button(self.main_frame, text="登出",
|
|
|
command=self.handle_logout)
|
|
|
logout_btn.grid(row=3, column=0, pady=30)
|
|
|
|
|
|
def select_level(self, level: str):
|
|
|
"""选择学习阶段"""
|
|
|
self.selected_level = level
|
|
|
self.show_question_count_input()
|
|
|
|
|
|
def show_question_count_input(self):
|
|
|
"""显示题目数量输入界面"""
|
|
|
self.clear_frame()
|
|
|
|
|
|
# 标题
|
|
|
title_label = ttk.Label(self.main_frame,
|
|
|
text=f"{self.selected_level}数学练习",
|
|
|
font=("Arial", 18, "bold"))
|
|
|
title_label.grid(row=0, column=0, pady=30)
|
|
|
|
|
|
# 题目数量输入
|
|
|
count_frame = ttk.Frame(self.main_frame)
|
|
|
count_frame.grid(row=1, column=0, pady=20)
|
|
|
|
|
|
ttk.Label(count_frame, text="请输入题目数量:").grid(row=0, column=0, padx=10)
|
|
|
self.question_count_entry = ttk.Entry(count_frame, width=10)
|
|
|
self.question_count_entry.grid(row=0, column=1, padx=10)
|
|
|
self.question_count_entry.insert(0, "10") # 默认10题
|
|
|
|
|
|
# 开始按钮
|
|
|
start_btn = ttk.Button(self.main_frame, text="开始答题",
|
|
|
command=self.start_test)
|
|
|
start_btn.grid(row=2, column=0, pady=20)
|
|
|
|
|
|
# 返回按钮
|
|
|
back_btn = ttk.Button(self.main_frame, text="返回",
|
|
|
command=self.show_level_selection_screen)
|
|
|
back_btn.grid(row=3, column=0, pady=10)
|
|
|
|
|
|
def start_test(self):
|
|
|
"""开始测试"""
|
|
|
try:
|
|
|
question_count = int(self.question_count_entry.get())
|
|
|
if question_count <= 0:
|
|
|
raise ValueError("题目数量必须大于0")
|
|
|
except ValueError:
|
|
|
messagebox.showerror("错误", "请输入有效的题目数量")
|
|
|
return
|
|
|
|
|
|
# 生成题目
|
|
|
self.current_questions = self.question_generator.generate_test_paper(
|
|
|
self.selected_level, question_count)
|
|
|
self.current_question_index = 0
|
|
|
self.user_answers = []
|
|
|
|
|
|
if not self.current_questions:
|
|
|
messagebox.showerror("错误", "题目生成失败")
|
|
|
return
|
|
|
|
|
|
self.show_question()
|
|
|
|
|
|
def show_question(self):
|
|
|
"""显示当前题目"""
|
|
|
if self.current_question_index >= len(self.current_questions):
|
|
|
self.show_result()
|
|
|
return
|
|
|
|
|
|
self.clear_frame()
|
|
|
|
|
|
question_data = self.current_questions[self.current_question_index]
|
|
|
|
|
|
# 进度显示
|
|
|
progress_label = ttk.Label(self.main_frame,
|
|
|
text=f"第 {self.current_question_index + 1} 题 / 共 {len(self.current_questions)} 题")
|
|
|
progress_label.grid(row=0, column=0, pady=10)
|
|
|
|
|
|
# 题目显示
|
|
|
question_label = ttk.Label(self.main_frame, text=question_data["question"],
|
|
|
font=("Arial", 16, "bold"))
|
|
|
question_label.grid(row=1, column=0, pady=30)
|
|
|
|
|
|
# 选项
|
|
|
self.answer_var = tk.StringVar()
|
|
|
options_frame = ttk.Frame(self.main_frame)
|
|
|
options_frame.grid(row=2, column=0, pady=20)
|
|
|
|
|
|
for i, option in enumerate(question_data["options"]):
|
|
|
radio_btn = ttk.Radiobutton(options_frame, text=f"{chr(65+i)}. {option}",
|
|
|
variable=self.answer_var, value=str(option))
|
|
|
radio_btn.grid(row=i, column=0, sticky=tk.W, pady=5)
|
|
|
|
|
|
# 提交按钮
|
|
|
submit_btn = ttk.Button(self.main_frame, text="提交答案",
|
|
|
command=self.submit_answer)
|
|
|
submit_btn.grid(row=3, column=0, pady=30)
|
|
|
|
|
|
def submit_answer(self):
|
|
|
"""提交答案"""
|
|
|
selected_answer = self.answer_var.get()
|
|
|
|
|
|
if not selected_answer:
|
|
|
messagebox.showerror("错误", "请选择一个答案")
|
|
|
return
|
|
|
|
|
|
# 记录用户答案
|
|
|
question_data = self.current_questions[self.current_question_index]
|
|
|
is_correct = int(selected_answer) == question_data["correct_answer"]
|
|
|
|
|
|
self.user_answers.append({
|
|
|
"question": question_data["question"],
|
|
|
"user_answer": int(selected_answer),
|
|
|
"correct_answer": question_data["correct_answer"],
|
|
|
"is_correct": is_correct
|
|
|
})
|
|
|
|
|
|
# 下一题
|
|
|
self.current_question_index += 1
|
|
|
self.show_question()
|
|
|
|
|
|
def show_result(self):
|
|
|
"""显示测试结果"""
|
|
|
self.clear_frame()
|
|
|
|
|
|
# 计算分数
|
|
|
correct_count = sum(1 for answer in self.user_answers if answer["is_correct"])
|
|
|
total_count = len(self.user_answers)
|
|
|
score = self.score_calculator.calculate_score(correct_count, total_count)
|
|
|
comment = self.score_calculator.get_grade_comment(score)
|
|
|
|
|
|
# 结果显示
|
|
|
result_frame = ttk.Frame(self.main_frame)
|
|
|
result_frame.grid(row=0, column=0, pady=30)
|
|
|
|
|
|
ttk.Label(result_frame, text="测试完成!",
|
|
|
font=("Arial", 20, "bold")).grid(row=0, column=0, pady=10)
|
|
|
|
|
|
ttk.Label(result_frame, text=f"正确题数: {correct_count}/{total_count}",
|
|
|
font=("Arial", 14)).grid(row=1, column=0, pady=5)
|
|
|
|
|
|
ttk.Label(result_frame, text=f"得分: {score} 分",
|
|
|
font=("Arial", 16, "bold")).grid(row=2, column=0, pady=10)
|
|
|
|
|
|
ttk.Label(result_frame, text=comment,
|
|
|
font=("Arial", 12)).grid(row=3, column=0, pady=5)
|
|
|
|
|
|
# 按钮框架
|
|
|
button_frame = ttk.Frame(self.main_frame)
|
|
|
button_frame.grid(row=1, column=0, pady=30)
|
|
|
|
|
|
# 继续做题按钮
|
|
|
continue_btn = ttk.Button(button_frame, text="继续做题",
|
|
|
command=self.show_level_selection_screen)
|
|
|
continue_btn.grid(row=0, column=0, padx=20)
|
|
|
|
|
|
# 退出按钮
|
|
|
exit_btn = ttk.Button(button_frame, text="退出",
|
|
|
command=self.handle_logout)
|
|
|
exit_btn.grid(row=0, column=1, padx=20)
|
|
|
|
|
|
def handle_logout(self):
|
|
|
"""处理登出"""
|
|
|
self.data_manager.logout()
|
|
|
self.show_welcome_screen()
|
|
|
|
|
|
def show_email_config(self):
|
|
|
"""显示邮箱配置界面"""
|
|
|
EmailConfigWindow(self.root, self.data_manager)
|
|
|
|
|
|
def run(self):
|
|
|
"""运行应用"""
|
|
|
self.root.mainloop()
|
|
|
|
|
|
|
|
|
if __name__ == "__main__":
|
|
|
app = MathLearningApp()
|
|
|
app.run() |