Reputation: 135
I am coding a Hangman GUI for an assignment in school. I am new to coding so I haven't got a lot of knowledge of many modules so my code may be unnecessarily long. I have put a status bar at the bottom of my window to inform the user if their guesses are too long or already guessed. After 2 seconds, the text should revert back to "Everything's fine :)"
but the window becomes unresponsive for 2 seconds and the label does not inform the user of invalid guesses.
Note: I am new to programming so please be as basic as possible with your explanations.
Many Thanks!
The problem is in the last function
Here is the code:
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()
Upvotes: 0
Views: 310
Reputation: 2690
The root.after call needs a callable function as its argument, so that the statusBar.config event is called in 2 seconds as opposed to immediately. It will make the GUI responsive if you do this.
root.after(2000, lambda: statusBar.config(text="Everything's fine :)"))
Upvotes: 1