2017-07-01 60 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有什麼區別? –