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() self.wrong_attempts = 0 # 记录密码错误次数的计数器 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: self.wrong_attempts += 1 # 每次密码错误,计数器加1 messagebox.showerror("错误", "用户名或密码错误!") if self.wrong_attempts >= 3: # 检查错误次数是否达到限制 messagebox.showerror("警告", "密码错误次数过多,程序即将退出。") self.quit() # 退出程序 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=20, pady=20) self.next_button = tk.Button(self, text="下一个单词", command=self.show_next_word) self.next_button.pack(side=tk.RIGHT, 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("", 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(): self.user_entry.config(fg="green") # 将输入框文字颜色设为绿色 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("") # 避免在显示答案时响应回车键 self.user_entry.bind("", 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] > 2: 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("", 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.geometry("400x300") # 数据库连接设置 self.db = pymysql.connect( host="localhost", # MySQL服务器地址 user="root", # 数据库用户名 password="21412030117", # 数据库密码 database="word", # 数据库名 charset='utf8mb4', # 字符编码,根据需要调整 cursorclass=pymysql.cursors.DictCursor # 使用字典游标,方便通过列名访问数据 ) self.cursor = self.db.cursor() self.text_widget = tk.Text(self, wrap=tk.WORD, width=40, height=10) self.text_widget.pack(expand=True, fill=tk.BOTH, padx=10, pady=10) # 获取易错单词 self.fetch_and_display_mistaken_words() def fetch_and_display_mistaken_words(self): self.cursor.execute("SELECT `word`, `meaning` FROM `words` WHERE `easily_mistaken` = 1") mistaken_words = self.cursor.fetchall() if mistaken_words: self.display_words(mistaken_words) else: messagebox.showinfo("提示", "没有易错单词可供复习!") self.destroy() def display_words(self, words): # 使用Text控件显示单词和意义 for idx, word_info in enumerate(words, start=1): text_to_insert = f"{idx}. 单词: {word_info['word']}, 意义: {word_info['meaning']}\n" self.text_widget.insert(tk.END, text_to_insert) # 自动滚动到底部 self.text_widget.see(tk.END) def on_closing(self): self.db.close() self.destroy() def start_application(): root = tk.Tk() root.withdraw() # 隐藏根窗口,因为我们直接使用Toplevel作为登录界面 LoginPage(master=root) # 将主窗口作为master传给LoginPage,便于后续操作 root.mainloop() # 主循环在此启动,控制整个应用的生命周期 if __name__ == "__main__": start_application()