You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

259 lines
10 KiB

6 months ago
import tkinter as tk
from tkinter import messagebox
import random
import pymysql
class LoginPage(tk.Toplevel):
def __init__(self, master=None):
super().__init__(master)
self.title("登录")
self.geometry("200x200")
self.username_var = tk.StringVar()
self.password_var = tk.StringVar()
tk.Label(self, text="用户名:").pack()
tk.Entry(self, textvariable=self.username_var).pack()
tk.Label(self, text="密码:").pack()
tk.Entry(self, show="*", textvariable=self.password_var).pack()
tk.Button(self, text="登录", command=self.login).pack(pady=10)
def login(self):
username = self.username_var.get()
password = self.password_var.get()
if username == "a" and password == "123456":
self.master.destroy() # 关闭主窗口(如果有),这里假设直接关闭自身也行,取决于实际结构
MainApp().mainloop() # 登录成功后实例化MainApp并启动其主循环
else:
messagebox.showerror("错误", "用户名或密码错误!") # 登录失败,保持登录界面打开供用户重试
class MainApp(tk.Tk):
def __init__(self):
super().__init__()
self.title("单词学习")
self.geometry("200x200")
# 创建三个按钮
tk.Button(self, text="学习新单词", command=self.open_window1).pack(fill=tk.X, padx=10, pady=5)
tk.Button(self, text="复习单词", command=self.open_window2).pack(fill=tk.X, padx=10, pady=5)
tk.Button(self, text="易错单词查看", command=self.open_window3).pack(fill=tk.X, padx=10, pady=5)
def open_window1(self):
Window1(self)
def open_window2(self):
Window2(self)
def open_window3(self):
Window3(self)
class Window1(tk.Toplevel):
def __init__(self, master):
super().__init__(master)
self.title("单词学习界面")
# 初始化MySQL数据库连接
self.conn = pymysql.connect(
host="localhost", # MySQL服务器地址
user="root", # 数据库用户名
password="21412030117", # 数据库密码
database="word", # 数据库名
charset='utf8mb4', # 字符编码,根据需要调整
cursorclass=pymysql.cursors.DictCursor # 使用字典游标,方便通过列名访问数据
)
self.cursor = self.conn.cursor()
self.word_frame = tk.Frame(self)
self.word_frame.pack(padx=10, pady=10)
self.next_button = tk.Button(self, text="下一个单词", command=self.show_next_word)
self.next_button.pack(side=tk.RIGHT, padx=5, pady=5)
self.prev_button = tk.Button(self, text="上一个单词") # 实现逻辑待补充
self.prev_button.pack(side=tk.LEFT, padx=5, pady=5)
self.show_next_word() # 初始显示一个单词
def show_next_word(self):
# 查询并获取一个未学习的单词
query = ("SELECT word, meaning FROM words WHERE learned = 0 ORDER BY RAND() LIMIT 1")
self.cursor.execute(query)
word_row = self.cursor.fetchone()
if word_row:
word, meaning = word_row['word'], word_row['meaning'] # 使用字典访问列
self.display_word(word, meaning)
# 标记该单词为已学习
self.mark_word_as_learned(word)
else:
messagebox.showinfo("提示", "所有单词都已学习过!")
def display_word(self, word, meaning):
"""显示单词及其意义"""
for widget in self.word_frame.winfo_children():
widget.destroy()
tk.Label(self.word_frame, text=f"单词: {word}").pack(anchor=tk.W)
tk.Label(self.word_frame, text=f"意义: {meaning}").pack(anchor=tk.W)
def mark_word_as_learned(self, word):
"""将单词标记为已学习"""
update_query = ("UPDATE words SET learned = 1 WHERE word = %s")
self.cursor.execute(update_query, (word,))
self.conn.commit()
class Window2(tk.Toplevel):
def __init__(self, master):
super().__init__(master)
self.title("单词拼写测试")
self.conn = pymysql.connect(
host="localhost",
user="root",
password="21412030117",
database="word",
charset='utf8mb4',
cursorclass=pymysql.cursors.DictCursor
)
self.cursor = self.conn.cursor()
self.setup_ui()
self.protocol("WM_DELETE_WINDOW", self.on_closing)
self.word_error_count = {} # 新增:存储单词错误次数的字典
def setup_ui(self):
self.word_label = tk.Label(self, text="", font=("Arial", 16))
self.word_label.pack(pady=10)
self.entry_var = tk.StringVar()
self.user_entry = tk.Entry(self, textvariable=self.entry_var, font=("Arial", 14))
self.user_entry.pack(ipady=5, pady=10)
self.result_label = tk.Label(self, text="", fg="black", font=("Arial", 12))
self.result_label.pack(pady=5)
self.next_button = tk.Button(self, text="下一个单词", state=tk.DISABLED, command=self.show_next_word)
self.next_button.pack(pady=10)
self.show_next_word() # 初始化显示一个单词
def show_next_word(self):
self.next_button.config(state=tk.DISABLED) # 禁用按钮防止重复点击
self.cursor.execute("SELECT `word`, `meaning` FROM `words` WHERE `learned` = 1 ORDER BY RAND() LIMIT 1")
word_row = self.cursor.fetchone()
if word_row:
self.current_word = word_row['word']
self.current_meaning = word_row['meaning']
self.word_label.config(text=f"含义:{self.current_meaning}")
self.entry_var.set("") # 清空输入框
self.result_label.config(text="")
self.user_entry.bind("<Return>", lambda event: self.check_spelling()) # 绑定回车键检查拼写
else:
messagebox.showinfo("提示", "没有更多已学习的单词可供测试!")
self.destroy()
def check_spelling(self):
user_input = self.entry_var.get().strip().lower()
if user_input == self.current_word.lower():
6 months ago
self.user_entry.config(fg="green") # 将输入框文字颜色设为绿色
6 months ago
self.result_label.config(text="正确!", fg="green")
self.next_button.config(state=tk.NORMAL) # 正确后启用按钮
self.word_error_count[self.current_word] = 0 # 重置错误计数
else:
self.result_label.config(text=f"错误!", fg="red")
self.user_entry.delete(0, tk.END) # 清空输入框并显示正确答案
self.user_entry.insert(0, self.current_word) # 在输入框中显示正确答案
self.user_entry.config(fg="red") # 将输入框文字颜色设为红色
self.user_entry.unbind("<Return>") # 避免在显示答案时响应回车键
self.user_entry.bind("<Button-1>", lambda event: self.clear_and_rebind(event)) # 绑定左键点击事件以清除并重新绑定
# 更新错误计数
if self.current_word in self.word_error_count:
self.word_error_count[self.current_word] += 1
else:
self.word_error_count[self.current_word] = 1
# 达到错误次数限制时更新数据库
if self.word_error_count[self.current_word] > 3:
self.update_easily_mistaken_in_db()
def update_easily_mistaken_in_db(self):
"""更新数据库中单词的easily_mistaken字段为1"""
try:
update_query = (
"UPDATE `words` SET `easily_mistaken` = 1 "
"WHERE `word` = %s AND `easily_mistaken` != 1"
)
self.cursor.execute(update_query, (self.current_word,))
self.conn.commit()
print(f"单词'{self.current_word}'标记为易错单词。")
except Exception as e:
print(f"更新数据库时出错:{e}")
def clear_and_rebind(self, event):
self.user_entry.delete(0, tk.END) # 清空输入框
self.user_entry.config(fg="black") # 重置输入框文字颜色为黑色
self.user_entry.bind("<Return>", lambda event: self.check_spelling()) # 重新绑定回车键事件
def on_closing(self):
self.conn.close()
self.destroy()
class Window3(tk.Toplevel):
def __init__(self, master):
super().__init__(master)
self.title("易错单词复习")
self.conn = pymysql.connect(
host="localhost",
user="root",
password="21412030117",
database="word",
charset='utf8mb4',
cursorclass=pymysql.cursors.DictCursor
)
self.cursor = self.conn.cursor()
self.setup_ui()
self.show_next_mistaken_word() # 初始化显示一个易错单词
def setup_ui(self):
self.word_label = tk.Label(self, text="", font=("Arial", 16))
self.word_label.pack(pady=10)
self.next_button = tk.Button(self, text="下一个单词", command=self.show_next_mistaken_word)
self.next_button.pack(pady=10)
def show_next_mistaken_word(self):
self.cursor.execute("SELECT `word`, `meaning` FROM `words` WHERE `easily_mistaken` = 1 ORDER BY RAND() LIMIT 1")
word_row = self.cursor.fetchone()
if word_row:
self.current_word = word_row['word']
self.current_meaning = word_row['meaning']
self.word_label.config(text=f"含义:{self.current_meaning}")
else:
messagebox.showinfo("提示", "没有更多易错单词可供复习!")
self.destroy()
def on_closing(self):
self.conn.close()
self.destroy()
def protocol(self, event):
self.on_closing()
# 在创建Window3实例的地方确保调用protocol方法绑定关闭事件
#window3 = Window3(root)
#window3.protocol("WM_DELETE_WINDOW", window3.on_closing)
def start_application():
root = tk.Tk()
root.withdraw() # 隐藏根窗口因为我们直接使用Toplevel作为登录界面
LoginPage(master=root) # 将主窗口作为master传给LoginPage便于后续操作
root.mainloop() # 主循环在此启动,控制整个应用的生命周期
if __name__ == "__main__":
start_application()