Files
PeojectTWT/UI.py
2025-10-11 10:47:07 +08:00

389 lines
15 KiB
Python

import tkinter as tk
from tkinter import ttk, messagebox, filedialog
import json
import random
from datetime import datetime
import os
class ModernUIApp:
def __init__(self, root):
self.root = root
self.root.title("托福单词默写系统")
self.root.geometry("1000x700")
self.root.configure(bg='#f0f0f0')
# 设置现代化样式
self.setup_styles()
# 创建主界面
self.create_main_interface()
# 托福单词库(简化版)
self.toefl_words = [
"abandon", "ability", "abnormal", "abolish", "abrupt",
"absorb", "abstract", "abundant", "access", "accident",
"accommodate", "accompany", "accomplish", "account", "accurate",
"achieve", "acknowledge", "acquire", "adapt", "adequate",
"adjust", "administer", "admire", "admit", "adopt",
"advance", "advantage", "adventure", "advertise", "advise",
"affect", "afford", "aggressive", "agree", "aid",
"aim", "alert", "alien", "alike", "alive",
"allocate", "allow", "ally", "alone", "alter",
"alternative", "amateur", "amaze", "ambition", "amount",
"ample", "analyze", "anchor", "ancient", "angle"
]
self.selected_words = []
self.current_word_index = 0
self.mistakes = []
def setup_styles(self):
# 配置样式
style = ttk.Style()
style.theme_use('clam')
# 自定义按钮样式
style.configure('Modern.TButton',
padding=10,
font=('Arial', 12, 'bold'),
foreground='#ffffff',
background='#4a90e2',
borderwidth=0)
style.map('Modern.TButton',
background=[('active', '#357abd')])
# 自定义标签样式
style.configure('Title.TLabel',
font=('Arial', 16, 'bold'),
foreground='#2c3e50',
background='#f0f0f0')
style.configure('Subtitle.TLabel',
font=('Arial', 12),
foreground='#7f8c8d',
background='#f0f0f0')
def create_main_interface(self):
# 创建主框架
main_frame = tk.Frame(self.root, bg='#f0f0f0')
main_frame.pack(fill=tk.BOTH, expand=True, padx=20, pady=20)
# 标题区域
title_frame = tk.Frame(main_frame, bg='#f0f0f0')
title_frame.pack(fill=tk.X, pady=(0, 20))
title_label = ttk.Label(title_frame, text="托福单词默写系统", style='Title.TLabel')
title_label.pack(side=tk.LEFT)
# 模式选择区域
mode_frame = tk.Frame(main_frame, bg='#f0f0f0')
mode_frame.pack(fill=tk.X, pady=(0, 20))
ttk.Label(mode_frame, text="选择使用模式:", style='Subtitle.TLabel').pack(side=tk.LEFT)
self.teacher_btn = ttk.Button(mode_frame, text="老师端",
style='Modern.TButton',
command=self.show_teacher_interface)
self.teacher_btn.pack(side=tk.LEFT, padx=(20, 10))
self.student_btn = ttk.Button(mode_frame, text="学生端",
style='Modern.TButton',
command=self.show_student_interface)
self.student_btn.pack(side=tk.LEFT, padx=10)
# 内容区域
self.content_frame = tk.Frame(main_frame, bg='#ffffff', relief=tk.RAISED, bd=1)
self.content_frame.pack(fill=tk.BOTH, expand=True)
# 显示欢迎界面
self.show_welcome_interface()
def show_welcome_interface(self):
self.clear_content_frame()
welcome_frame = tk.Frame(self.content_frame, bg='#ffffff')
welcome_frame.pack(expand=True)
ttk.Label(welcome_frame, text="欢迎使用托福单词默写系统",
font=('Arial', 18, 'bold'),
foreground='#2c3e50',
background='#ffffff').pack(pady=20)
ttk.Label(welcome_frame, text="请选择您要使用的模式:老师端 或 学生端",
font=('Arial', 12),
foreground='#7f8c8d',
background='#ffffff').pack(pady=10)
def show_teacher_interface(self):
self.clear_content_frame()
# 创建笔记本控件用于选项卡
notebook = ttk.Notebook(self.content_frame)
notebook.pack(fill=tk.BOTH, expand=True, padx=10, pady=10)
# 单词选择页面
word_select_frame = tk.Frame(notebook, bg='#ffffff')
notebook.add(word_select_frame, text="单词选择")
self.create_word_selection_interface(word_select_frame)
# 默写控制页面
dictation_frame = tk.Frame(notebook, bg='#ffffff')
notebook.add(dictation_frame, text="开始默写")
self.create_dictation_interface(dictation_frame)
def create_word_selection_interface(self, parent):
# 标题
ttk.Label(parent, text="选择托福单词",
font=('Arial', 14, 'bold'),
background='#ffffff').pack(pady=10)
# 搜索框
search_frame = tk.Frame(parent, bg='#ffffff')
search_frame.pack(fill=tk.X, padx=20, pady=10)
ttk.Label(search_frame, text="搜索:", background='#ffffff').pack(side=tk.LEFT)
self.search_var = tk.StringVar()
search_entry = ttk.Entry(search_frame, textvariable=self.search_var, width=30)
search_entry.pack(side=tk.LEFT, padx=10)
search_entry.bind('<KeyRelease>', self.filter_words)
# 单词列表框架
list_frame = tk.Frame(parent, bg='#ffffff')
list_frame.pack(fill=tk.BOTH, expand=True, padx=20, pady=10)
# 创建Treeview显示单词
columns = ('单词', '状态')
self.word_tree = ttk.Treeview(list_frame, columns=columns, show='headings', height=15)
# 设置列标题
self.word_tree.heading('单词', text='单词')
self.word_tree.heading('状态', text='状态')
self.word_tree.column('单词', width=200)
self.word_tree.column('状态', width=100)
# 滚动条
scrollbar = ttk.Scrollbar(list_frame, orient=tk.VERTICAL, command=self.word_tree.yview)
self.word_tree.configure(yscrollcommand=scrollbar.set)
self.word_tree.pack(side=tk.LEFT, fill=tk.BOTH, expand=True)
scrollbar.pack(side=tk.RIGHT, fill=tk.Y)
# 填充单词数据
self.populate_word_list()
# 按钮区域
button_frame = tk.Frame(parent, bg='#ffffff')
button_frame.pack(fill=tk.X, padx=20, pady=10)
ttk.Button(button_frame, text="全选",
style='Modern.TButton',
command=self.select_all_words).pack(side=tk.LEFT, padx=5)
ttk.Button(button_frame, text="取消全选",
style='Modern.TButton',
command=self.deselect_all_words).pack(side=tk.LEFT, padx=5)
ttk.Button(button_frame, text="随机选择20个",
style='Modern.TButton',
command=self.random_select_words).pack(side=tk.LEFT, padx=5)
ttk.Button(button_frame, text="导出配置文件",
style='Modern.TButton',
command=self.export_config).pack(side=tk.RIGHT, padx=5)
# 统计信息
self.stats_label = ttk.Label(button_frame, text="已选择: 0 个单词",
background='#ffffff')
self.stats_label.pack(side=tk.RIGHT, padx=20)
def populate_word_list(self):
self.word_tree.delete(*self.word_tree.get_children())
for word in self.toefl_words:
status = "✓ 已选择" if word in self.selected_words else "○ 未选择"
self.word_tree.insert('', tk.END, values=(word, status))
def filter_words(self, event=None):
# 简化的过滤功能
search_term = self.search_var.get().lower()
if search_term:
filtered_words = [word for word in self.toefl_words if search_term in word.lower()]
else:
filtered_words = self.toefl_words
self.word_tree.delete(*self.word_tree.get_children())
for word in filtered_words:
status = "✓ 已选择" if word in self.selected_words else "○ 未选择"
self.word_tree.insert('', tk.END, values=(word, status))
def select_all_words(self):
self.selected_words = self.toefl_words.copy()
self.populate_word_list()
self.update_stats()
def deselect_all_words(self):
self.selected_words = []
self.populate_word_list()
self.update_stats()
def random_select_words(self):
self.selected_words = random.sample(self.toefl_words, min(20, len(self.toefl_words)))
self.populate_word_list()
self.update_stats()
def update_stats(self):
self.stats_label.config(text=f"已选择: {len(self.selected_words)} 个单词")
def export_config(self):
if not self.selected_words:
messagebox.showwarning("警告", "请先选择单词!")
return
filename = filedialog.asksaveasfilename(
defaultextension=".json",
filetypes=[("JSON files", "*.json"), ("All files", "*.*")],
title="保存配置文件"
)
if filename:
config = {
"words": self.selected_words,
"created_time": datetime.now().isoformat(),
"version": "1.0"
}
try:
with open(filename, 'w', encoding='utf-8') as f:
json.dump(config, f, ensure_ascii=False, indent=2)
messagebox.showinfo("成功", f"配置文件已保存到:\n{filename}")
except Exception as e:
messagebox.showerror("错误", f"保存失败: {str(e)}")
def show_student_interface(self):
self.clear_content_frame()
# 标题
ttk.Label(self.content_frame, text="学生端 - 导入配置",
font=('Arial', 14, 'bold'),
background='#ffffff').pack(pady=20)
# 导入区域
import_frame = tk.Frame(self.content_frame, bg='#ffffff')
import_frame.pack(fill=tk.BOTH, expand=True, padx=50, pady=20)
ttk.Label(import_frame, text="请导入老师端生成的配置文件",
font=('Arial', 12),
background='#ffffff').pack(pady=10)
ttk.Button(import_frame, text="选择配置文件",
style='Modern.TButton',
command=self.import_config).pack(pady=20)
# 显示导入的单词信息
self.word_info_label = ttk.Label(import_frame,
text="尚未导入配置文件",
font=('Arial', 10),
background='#ffffff')
self.word_info_label.pack(pady=10)
def import_config(self):
filename = filedialog.askopenfilename(
filetypes=[("JSON files", "*.json"), ("All files", "*.*")],
title="选择配置文件"
)
if filename:
try:
with open(filename, 'r', encoding='utf-8') as f:
config = json.load(f)
self.selected_words = config.get('words', [])
created_time = config.get('created_time', '未知')
self.word_info_label.config(
text=f"已导入 {len(self.selected_words)} 个单词\n创建时间: {created_time}"
)
messagebox.showinfo("成功", f"成功导入 {len(self.selected_words)} 个单词!")
except Exception as e:
messagebox.showerror("错误", f"导入失败: {str(e)}")
def create_dictation_interface(self, parent):
# 标题
ttk.Label(parent, text="开始默写",
font=('Arial', 14, 'bold'),
background='#ffffff').pack(pady=10)
# 控制按钮
control_frame = tk.Frame(parent, bg='#ffffff')
control_frame.pack(fill=tk.X, padx=20, pady=10)
ttk.Button(control_frame, text="开始默写",
style='Modern.TButton',
command=self.start_dictation).pack(side=tk.LEFT, padx=5)
ttk.Button(control_frame, text="暂停",
style='Modern.TButton',
command=self.pause_dictation).pack(side=tk.LEFT, padx=5)
ttk.Button(control_frame, text="结束",
style='Modern.TButton',
command=self.end_dictation).pack(side=tk.LEFT, padx=5)
# 默写显示区域
dictation_frame = tk.Frame(parent, bg='#ffffff')
dictation_frame.pack(fill=tk.BOTH, expand=True, padx=20, pady=10)
# 当前单词显示
self.current_word_label = ttk.Label(dictation_frame,
text="点击'开始默写'开始",
font=('Arial', 24, 'bold'),
background='#ffffff')
self.current_word_label.pack(expand=True)
# 进度信息
self.progress_label = ttk.Label(dictation_frame,
text="进度: 0/0",
font=('Arial', 12),
background='#ffffff')
self.progress_label.pack(pady=10)
def start_dictation(self):
if not self.selected_words:
messagebox.showwarning("警告", "请先在'单词选择'页面选择单词!")
return
self.current_word_index = 0
self.mistakes = []
self.show_next_word()
def show_next_word(self):
if self.current_word_index < len(self.selected_words):
word = self.selected_words[self.current_word_index]
self.current_word_label.config(text=word)
self.progress_label.config(
text=f"进度: {self.current_word_index + 1}/{len(self.selected_words)}"
)
else:
self.end_dictation()
def pause_dictation(self):
messagebox.showinfo("暂停", "默写已暂停")
def end_dictation(self):
self.current_word_label.config(text="默写结束")
self.progress_label.config(text=f"完成: {len(self.selected_words)}/{len(self.selected_words)}")
messagebox.showinfo("完成", f"默写完成!共 {len(self.selected_words)} 个单词")
def clear_content_frame(self):
for widget in self.content_frame.winfo_children():
widget.destroy()
def main():
root = tk.Tk()
app = ModernUIApp(root)
root.mainloop()
if __name__ == "__main__":
main()