2017-07-01 56 views
0

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

的问题是在过去的功能root.after方法冻结了我的窗口(Tkinter Python 3)

下面是代码:

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() 
+0

你可以减少你的代码到相关部分,如果问题是在一行中,通过100多行阅读是没有意义的。 – SneakyTurtle

+0

非常抱歉。我包括了整个代码,因为之前没有问题,但过了一段时间后问题出现了 –

回答

1

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

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

“需要一个lambda”并不完全正确。它需要一个_callable_,它可以是一个函数,或者你可以使用'lambda'或'functools.partial'命名。 –

+0

谢谢!你是一位英雄!顺便说一下,lambda和def有什么区别? –