You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

布尔变量作用域问题导致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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.07 09:45:03