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("", 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] > 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("", 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.fetch_mistaken_words() # UI设置 self.word_label = tk.Label(self, text="", font=("Arial", 14)) self.word_label.pack(pady=20) # 按钮 button_frame = tk.Frame(self) button_frame.pack(pady=10) tk.Button(button_frame, text="上一个单词", command=self.show_previous_word, state=tk.DISABLED).pack( side=tk.LEFT, padx=10) tk.Button(button_frame, text="下一个单词", command=self.show_next_word).pack(side=tk.RIGHT, padx=10) # 初始化显示第一个单词 self.show_current_word() def fetch_mistaken_words(self): self.cursor.execute("SELECT `word`, `meaning` FROM `words` WHERE `easily_mistaken` = 1 ORDER BY `id`") self.mistaken_words = self.cursor.fetchall() self.current_index = 0 self.total_words = len(self.mistaken_words) if self.total_words == 0: messagebox.showinfo("提示", "没有易错单词可供复习!") self.destroy() def show_current_word(self): if self.total_words > 0: word_info = self.mistaken_words[self.current_index] self.word_label.config(text=f"单词: {word_info['word']}, 意义: {word_info['meaning']}") # 更新按钮状态 self.update_button_states() def show_next_word(self): if self.current_index < self.total_words - 1: self.current_index += 1 else: self.current_index = 0 self.show_current_word() def show_previous_word(self): if self.current_index > 0: self.current_index -= 1 else: self.current_index = self.total_words - 1 self.show_current_word() def update_button_states(self): if self.current_index == 0: self.button_previous.configure(state=tk.DISABLED) else: self.button_previous.configure(state=tk.NORMAL) if self.current_index == self.total_words - 1: self.button_next.configure(state=tk.DISABLED) else: self.button_next.configure(state=tk.NORMAL) def on_closing(self): # 关闭窗口前的清理工作,如关闭数据库连接 self.db.close() super().destroy() # 实例化Window3的正确位置 if __name__ == "__main__": root = tk.Tk() root.withdraw() # 如果需要隐藏主窗口 window3 = Window3(root) window3.protocol("WM_DELETE_WINDOW", window3.on_closing) window3.mainloop() def main(): # 初始化Tkinter的根窗口 root = tk.Tk() root.withdraw() # 可选:隐藏根窗口,如果你不打算显示它的话 # 创建并显示Window3实例 window3 = Window3(root) window3.protocol("WM_DELETE_WINDOW", window3.on_closing) window3.mainloop() # 开始Window3窗口的事件循环 def start_application(): root = tk.Tk() root.withdraw() # 隐藏根窗口,因为我们直接使用Toplevel作为登录界面 LoginPage(master=root) # 将主窗口作为master传给LoginPage,便于后续操作 root.mainloop() # 主循环在此启动,控制整个应用的生命周期 if __name__ == "__main__": start_application()