与我认为的布尔变量的范围作斗争 - tkinter window 不会退出

Having struggles with what I think is the scope of a boolean variable - tkinter window won't quit

抱歉,如果这个标题不是很有用,但这是我描述问题的最佳方式。当我故意将密码输入错误 3 次时,应该会出现一个弹出窗口我输入的密码错误次数太多,然后 window 应该退出并且程序应该结束。 实际上 发生的是弹出窗口显示得很好,但 tkinter window 没有退出而是留在那里。出于某种原因,我认为 quit() 函数不喜欢我的 while 循环。我提出“范围问题”是因为我不确定“授权”是否始终等于它的意思或我认为应该的意思。有什么建议吗?

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)

while(authorised == False and failed == False):
    def checkLogin():
        user1 = e1.get()==username1
        pass1 = e2.get()==password1
        user2 = e3.get()==username2
        pass2 = e4.get()==password2

        if (user1 and user2 and pass1 and pass2):
            global authorised
            authorised = True
            playerslogin.quit()
        else:
            global attempts
            attempts = attempts + 1
            if attempts == 3:
                playerslogin.quit()
                messagebox.showerror(title="Attempts exceeded", message="You have used all 3 attempts.")
                failed == True
            else: 
                authfail.config(text = f"Login failed. Attempts left: {3-attempts}")

    e1 = tk.Entry(playerslogin)
    e2 = tk.Entry(playerslogin, show = "*")
    e3 = tk.Entry(playerslogin)
    e4 = tk.Entry(playerslogin, show = "*")
    e5 = tk.Button(playerslogin, text = "Enter", command = checkLogin)

    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)

    playerslogin.mainloop()


#Login/authorisation code ends here, this is where the game begins

#Creating a deck and preparing the game
class Card:
  def __init__(self, colour, number):
    self.colour = colour
    self.number = number

  def getColour(self):
      return self.colour

  def getNumber(self):
      return self.number

#Cards are of colours Red, Yellow and Black, and go from 1 to 10

r1 = Card("Red", 1)
r2 = Card("Red", 2)
r3 = Card("Red", 3)
r4 = Card("Red", 4)
r5 = Card("Red", 5)
r6 = Card("Red", 6)
r7 = Card("Red", 7)
r8 = Card("Red", 8)
r9 = Card("Red", 9)
r10 = Card("Red", 10)

y1 = Card("Yellow", 1)
y2 = Card("Yellow", 2)
y3 = Card("Yellow", 3)
y4 = Card("Yellow", 4)
y5 = Card("Yellow", 5)
y6 = Card("Yellow", 6)
y7 = Card("Yellow", 7)
y8 = Card("Yellow", 8)
y9 = Card("Yellow", 9)
y10 = Card("Yellow", 10)

b1 = Card("Black", 1)
b2 = Card("Black", 2)
b3 = Card("Black", 3)
b4 = Card("Black", 4)
b5 = Card("Black", 5)
b6 = Card("Black", 6)
b7 = Card("Black", 7)
b8 = Card("Black", 8)
b9 = Card("Black", 9)
b10 = Card("Black", 10)

deck = [r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, y1, y2, y3, y4, y5, y6, y7, y8, y9, y10, b1, b2, b3, b4, b5, b6, b7, b8, b9, b10]

#function to check who wins
def checkwinner(card1, card2):
    colour1 = card1.getColour()
    number1 = card1.getNumber()
    colour2 = card2.getColour()
    number2 = card2.getNumber()

    if (colour1 == colour2):
        if (number1 > number2):
            return "player1"
        else:
            return "player2"
    else:
        if (colour1 == "Red"):
            if (colour2 == "Black"):
                return "player1"
            else:
                return "player2"
        elif (colour1 == "Yellow"):
            if (colour2 == "Red"):
                return "player1"
            else:
                return "player2"
        elif (colour1 == "Black"):
            if (colour2 == "Yellow"):
                return "player1"
            else:
                return "player2"

player1deck = []
player2deck = []

#game GUI goes here

while (authorised):
    shuffleddeck = []
    shuffleddeck = deck
    random.shuffle(shuffleddeck)
    maingame = tk.Tk()
    maingame.title("Louise's Card Game")

    maingame.geometry("1000x950")
    maingame.mainloop()

在 tkinter 主循环中,您应该使用 .destroy() 而不是 .quit(),另请参阅 How do I close a tkinter window? 的已接受答案。此外,您断言 'failed == True' 而不是设置它:

global failed
failed = True

因此在循环中更新您的身份验证,您将获得:

while(authorised == False and failed == False):
    def checkLogin():
        user1 = e1.get()==username1
        pass1 = e2.get()==password1
        user2 = e3.get()==username2
        pass2 = e4.get()==password2

        if (user1 and user2 and pass1 and pass2):
            global authorised
            authorised = True
            playerslogin.destroy()
        else:
            global attempts, failed
            attempts = attempts + 1
            if attempts == 3:
                playerslogin.destroy()
                messagebox.showerror(title="Attempts exceeded", message="You have used all 3 attempts.")
                failed = True
            else:
                authfail.config(text = f"Login failed. Attempts left: {3-attempts}")

    e1 = tk.Entry(playerslogin)
    e2 = tk.Entry(playerslogin, show = "*")
    e3 = tk.Entry(playerslogin)
    e4 = tk.Entry(playerslogin, show = "*")
    e5 = tk.Button(playerslogin, text = "Enter", command = checkLogin)

    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)

    playerslogin.mainloop()