在Python(特别是Tkinter)中调用变量时遇到问题

1 投票
1 回答
22 浏览
提问于 2025-04-12 13:42

我正在用tkinter创建一个小的猜字游戏,但我的“机会”变量出现了问题,这让我无法继续下去。我想知道有没有人能看看我的代码,帮我找出问题所在以及如何解决!(我收到了一个错误提示,说这个变量未定义,但我尝试了好几种方法都没能解决)

from tkinter import *
from tkinter import messagebox
import random

#Defines the main application size, title, and resizeability with name 'window'
window = Tk()
window.geometry('450x250')
window.resizable(False, False)
window.title("Hangman")
window.canvas = Canvas(window, width=450, height=250)
window.canvas.pack()

def gameEasy(*args):
    hangman = Tk()
    hangman.geometry('450x200')
    hangman.resizable(False, False)
    hangman.title("Hangman")
    hangman.canvas = Canvas(hangman, width=450, height=200)
    hangman.canvas.pack()

    hangman.canvas.create_line(50, 120, 70, 120)
    hangman.canvas.create_line(59, 120, 59, 80)
    hangman.canvas.create_line(59, 80, 39, 80)
    hangman.canvas.create_line(39, 80, 39, 85)

    wordlistEasy = '''cat dog apple stars movie hammer sprint farmer'''
    wordlistEasy = wordlistEasy.split(' ')
    word = random.choice(wordlistEasy)

    letterguessed = []
    chances = len(word) + 2
    correct = 0
    flag = 0
    X1 = 75
    Y1 = 120
    X2 = 85
    Y2 = 120

    for i in word:
        X1 += 12
        X2 += 12
        hangman.canvas.create_line(X1, Y1, X2, Y2, dash=(8,1))
    
    def main_loop(*args):
        Guess = str(GuessInput.get())
        global chances
        incorrectLabel.config(text="")

        while chances != 0 and flag == 0:
            chances -= 1

            if not Guess.isalpha() and Guess != "":
                incorrectLabel.config(text="Please input a LETTER!")
                chances += 1
                break
            elif len(Guess) > 1 and (Guess != word):
                incorrectLabel.config(text="Please input only one letter!")
                chances += 1
                break
            elif (Guess in letterguessed) and Guess != "":
                incorrectLabel.config(text="Letter already guessed!")
                chances += 1
                break
            else:
                letterguessed.append(Guess)
                letterList.config(text=(letterguessed))
                chancesLabel.config(text=f"Chances left: {chances}")
                chances -= 1
                break

        GuessInput.delete(0,"end") #Resets the entry box after each input

    GuessInput = StringVar()
    GuessInput = Entry(hangman, width=8, bd="1")
    GuessInput.place(x=15, y=31)
    GuessInput.focus_force()
    Guessbtn = Button(hangman, text="Guess", width=7, bd="1", command=main_loop).place(x=75, y=28)
    hangman.bind('<Return>', main_loop)

    lettersLabel = Label(hangman, text="Guessed letters:").place(x=220, y=5)
    letterList = Label(hangman, text="")
    letterList.place(x=220, y=20)
    chancesLabel = Label(hangman, text=f"Chances left: {chances}")
    chancesLabel.place(x=12, y=5)
    incorrectLabel = Label(hangman, text="", fg="red")
    incorrectLabel.place(x=12, y=52)

    hangman.mainloop()

def exit(*args):
    messagebox.showinfo("Thank You", "Thanks for playing!")
    window.destroy()

mainlabel = Label(window, text="Welcome to Hangman", font=("Arial Bold",14)).place(x=120, y=5)
introMessage = Message(window, text="This is a simple hangman program using Tkinter. To play, simply select a difficulty, to leave, select quit!", width=280)
introMessage.place(x=80, y=30)

difficultyLabel = Label(window, text="Select a difficulty", font=("Arial Bold",9)).place(x=170, y=70)
easybtn = Button(window, text = "Easy", width=10, bd="1", command=gameEasy).place(x=182, y=95) #Defining a button with properties
hardbtn = Button(window, text = "Hard", width=10, bd="1").place(x=182, y=120) #Defining a button with properties
window.canvas.create_line(175,150,265,150)
rulesbtn = Button(window, text = "Rules", width=10, bd="1").place(x=182, y=155) #Defining a button with properties
quitbtn = Button(window, text = "Quit", width=10, bd="1", command=exit).place(x=182, y=180) #Defining a button with properties

window.mainloop()

我尝试把机会变量设为全局的,也试过多种不同的方式调整函数调用的顺序等等。

1 个回答

0

chances 是在函数 gameEasy() 内部定义的一个局部变量,所以在嵌套的函数 main_loop() 中不应该把它声明为全局变量。你应该把它声明为 nonlocal 变量。

另外,避免创建多个 Tk() 的实例。对于子窗口,应该使用 Toplevel()

def gameEasy(*args):
    hangman = Toplevel()  # use Toplevel() instead of Tk() for child window
    ...
    def main_loop(*args):
        ...
        nonlocal chances    # declare chances as nonlocal variable
        ...
    ...

撰写回答