root.after方法冻结我的窗口(Tkinter Python 3)

时间:2017-07-01 14:26:51

标签: python tkinter

我正在为学校的作业编写一个Hangman GUI。我是编码的新手,所以我对许多模块没有很多了解,所以我的代码可能会不必要地长。我在窗口底部放置了一个状态栏,告知用户他们的猜测是否太长或已经猜到了。 2秒后,文本应恢复为"Everything's fine :)",但窗口将无响应2秒,标签不会通知用户无效的猜测。
注意:我是编程新手,所以请尽量说明您的解释。
非常感谢!

问题出在上一个功能

以下是代码:

from tkinter import *
from winsound import *
import random

root = Tk()
root.resizable(0, 0)

# Game Settings
word_choices = ["python", "flower", "lollipop", "umbrella",
                "brain", "wrist", "wheel", "dress",
                "caterpillar", "window", "penguin",
                "belt", "forehead", "earthquake", "dolphin",
                "magazine", "pillow", "computer"
                ]
word = (random.choice(word_choices))
turns = 8
guesses = []
clean_guesses = "Letters you have guessed:\t\n"
letters_shown = " _ " * len(word)

# Photos used
stage0 = PhotoImage(file="Stage 0.png")
stage1 = PhotoImage(file="Stage 1.png")
stage2 = PhotoImage(file="Stage 2.png")
stage3 = PhotoImage(file="Stage 3.png")
stage4 = PhotoImage(file="Stage 4.png")
stage5 = PhotoImage(file="Stage 5.png")
stage6 = PhotoImage(file="Stage 6.png")
stage7 = PhotoImage(file="Stage 7.png")
stage8 = PhotoImage(file="Stage 8.png")
win = PhotoImage(file="Win!.png")

# List containing all of the photos
stages = [stage0,
          stage1,
          stage2,
          stage3,
          stage4,
          stage5,
          stage6,
          stage7,
          stage8]

hangman_stage = stages[0]


def adding_letters():
    global letters_shown, guesses, clean_guesses
    if len(guess_box.get()) != 1:
        statusBar.config(text="Make sure you have only guessed one letter!")
        guess_box.delete(0, END)
        update_status_bar()
        return
    elif guess_box.get() in guesses:
        statusBar.config(text="You have already guessed this!")
        guess_box.delete(0, END)
        update_status_bar()
        return
    guesses.append((guess_box.get()).lower())
    clean_guesses = "Letters you have guessed:\t\n"
    x = 0
    for char in sorted(set(guesses)):
        clean_guesses += char + ", "
        x += 1
        if x >= 9:
            clean_guesses += "\n"
            x = 0
    status_label.config(text=clean_guesses)
    letters_shown = ""
    failed = 0
    letters_on_screen.config(text=letters_shown)
    for char in word:
        if char in guesses:
            letters_shown += " {} ".format(char)
        else:

            letters_shown += " _ "
            failed += 1
    letters_on_screen.config(text=letters_shown)
    if failed == 0:
        winning()
    letters_on_screen.config(text=letters_shown)
    guessing_mechanic()


def guessing_mechanic():
    global turns, hangman_stage
    global guesses
    global letters_shown
    global word
    guesses.append(guess_box.get())
    letters_on_screen.config(text=letters_shown)
    if guess_box.get() not in word:
        turns -= 1
        letters_on_screen.config(text=letters_shown)
        next_stage()
    if guess_box.get() in word:
        letters_on_screen.config(text=letters_shown)
    if hangman_stage == stage8:
        title.config(text="YOU LOST! :(")
        guess_box.grid_forget()
        status_label.config(text="The word was {}.".format(word))
    letters_on_screen.config(text=letters_shown)
    guess_box.delete(0, END)


def next_stage():
    global hangman_stage, stages
    hangman_stage = stages[stages.index(hangman_stage) + 1]
    hangman_pic.config(image=hangman_stage)
    letters_on_screen.config(text=letters_shown)


def winning():
    title.config(text="YOU WON!!!!!")
    guess_box.grid_forget()
    guess_confirm.grid_forget()
    hangman_pic.config(image=win)
    PlaySound('Wow SFX.wav', SND_FILENAME)


def update_status_bar():
    root.after(2000, statusBar.config(text="Everything's fine :)"))


title = Label(root, text="Welcome to Hangman!", font="Helvetica 28 bold italic", fg="light blue", bg="dark blue")
letters_on_screen = Label(root, text=letters_shown, font="Helvetica 22 bold", fg="black")
guess_box = Entry(root)
hangman_pic = Label(root, image=hangman_stage)
guess_confirm = Button(root, text="Press to submit guess", font="Helvetica 14",
                       command=adding_letters)
status_label = Label(root, text=clean_guesses, font="Helvetica 14 bold", fg="dark blue")
statusBar = Label(root, text="Nothing wrong so far", bd=1, relief=SUNKEN, anchor=W)

title.grid(columnspan=4, rowspan=1, sticky=N + E + S + W)
hangman_pic.grid(column=3, row=1, rowspan=3)
letters_on_screen.grid(row=1, column=0, columnspan=3, sticky=S)
guess_box.grid(row=2, column=0)
guess_confirm.grid(row=2, column=1, columnspan=2)
status_label.grid(row=3, columnspan=2)
statusBar.grid(row=4, columnspan=3, sticky=E + W)

root.mainloop()

1 个答案:

答案 0 :(得分:1)

root.after调用需要一个可调用函数作为其参数,以便在2秒内调用statusBar.config事件而不是立即调用。如果你这样做,它将使GUI响应。

root.after(2000, lambda: statusBar.config(text="Everything's fine :)"))