布尔变量作用域问题导致tkinter登录窗口输错3次密码后无法退出
修复方案
核心问题点
- 给
failed变量赋值时错误使用了相等判断符==,没有实际修改全局变量的值,导致外层while循环的终止条件永远无法触发,quit()仅退出当前mainloop后,代码会立刻进入下一轮循环,重新渲染窗口启动mainloop,所以窗口始终无法关闭 - 你将控件创建、登录校验函数的定义都放到了while循环内部,会导致每轮循环重复创建冗余控件,属于不必要的逻辑
quit()方法仅终止tkinter的事件循环,不会销毁已经渲染的窗口实体,需要搭配destroy()方法使用- 修改全局变量
failed前没有声明global,无法正确修改全局作用域的变量值
修复后的完整登录部分代码
import tkinter as tk from tkinter import messagebox import random username1 = "player1" password1 = "player1pass" username2 = "player2" password2 = "player2pass" authorised = False failed = False attempts = 0 playerslogin = tk.Tk() playerslogin.title("Authentication") playerslogin.geometry("325x110") # 控件只需要创建一次,不需要放到循环里 labeluser1 = tk.Label(playerslogin, text="Enter the first player's username:") labeluser1.grid(row=0) labelpass1 = tk.Label(playerslogin, text="Enter the first player's password:") labelpass1.grid(row=1) labeluser2 = tk.Label(playerslogin, text="Enter the second player's username:") labeluser2.grid(row=2) labelpass2 = tk.Label(playerslogin, text="Enter the second player's password:") labelpass2.grid(row=3) authfail = tk.Label(playerslogin, text="") authfail.grid(row=4) e1 = tk.Entry(playerslogin) e2 = tk.Entry(playerslogin, show = "*") e3 = tk.Entry(playerslogin) e4 = tk.Entry(playerslogin, show = "*") e5 = tk.Button(playerslogin, text = "Enter") e1.grid(row=0, column=1) e2.grid(row=1, column=1) e3.grid(row=2, column=1) e4.grid(row=3, column=1) e5.grid(row=4, column=1) # 校验函数只需要定义一次 def checkLogin(): global authorised, attempts, failed user1 = e1.get()==username1 pass1 = e2.get()==password1 user2 = e3.get()==username2 pass2 = e4.get()==password2 if (user1 and user2 and pass1 and pass2): authorised = True playerslogin.destroy() else: attempts = attempts + 1 if attempts == 3: messagebox.showerror(title="Attempts exceeded", message="You have used all 3 attempts.") failed = True playerslogin.destroy() else: authfail.config(text = f"Login failed. Attempts left: {3-attempts}") # 绑定按钮事件 e5.config(command=checkLogin) # 只需要启动一次mainloop playerslogin.mainloop() # 校验失败直接终止程序 if failed: exit()
其他优化建议
你后续游戏部分的代码里也存在相同的问题,不要把窗口创建、mainloop放到while循环里,会导致重复创建窗口,建议根据游戏逻辑调整触发时机,不要靠死循环控制窗口渲染。
内容的提问来源于stack exchange,提问作者KrazylassPlayz
相关产品推荐
相关产品推荐

