Reputation: 349
I am trying to build a "Number Guessing Game" using tkinter
, where you need to guess the number generated by the computer, by entering it in an Entry
widget.
This is the code:
import tkinter as tk
import random, sys
class GameWindow(tk.Frame):
def __init__(self, parent):
tk.Frame.__init__(self, parent, bg="#8ECEBD")
self.parent = parent
self.init_window()
self.cust_game()
self.actual_num = self.create_num()
def init_window(self):
self.parent.geometry("800x900+560+90")
self.parent.title("Guess The Number!")
self.scrollbar = tk.Scrollbar(self)
self.scrollbar.pack(side="right", fill="y")
exit_button = tk.Button(self, bg="#811B14", font="Helvetica 17 bold",
command=lambda: self.client_exit(), text="EXIT GAME!",
cursor="hand2", relief="groove")
exit_button.pack(fill="x", pady=10, padx=10)
welcome_label = tk.Label(self, bg="#8ECEBD", fg="#810007", text="Welcome to\nGUESS THE NUMBER!",
font="Helvetica 25 bold")
welcome_label.pack(pady=60)
def cust_game(self):
self.main_frame = tk.Frame(self, bg="#8ECEBD")
self.main_frame.pack(fill="x")
instructions_label = tk.Label(self.main_frame, bg="#8ECEBD", fg="#6F8100", font="Helvetica 15",
text="Enter a number between 0 and 100 down here:")
instructions_label.pack(pady=15)
self.entry = tk.Entry(self.main_frame, width=3, font="Helvetica 13 italic")
self.entry.pack()
submit_button = tk.Button(self.main_frame, text="Check!", font="Helvetica 13 bold", fg="#001F4C",
relief="groove", bg="#336600", activebackground="#254C00", cursor="hand2",
command=lambda: self.compare_numbers())
submit_button.pack(pady=5)
self.second_frame = tk.Frame(self, bg="#8ECEBD")
self.second_frame.pack(pady=30)
label = tk.Label(self.second_frame, bg="#8ECEBD", text="YOUR RESULTS:", font="Helvetica 15", fg="blue")
label.pack(pady=15)
self.answersbox = tk.Listbox(self.second_frame, bg="#8ECEBD", relief="groove", bd=0, height=13, width=39,
yscrollcommand=self.scrollbar.set, fg="#FF4800", font="Helvetica 15")
self.answersbox.pack()
self.scrollbar.config(command=self.answersbox.yview)
def compare_numbers(self):
num = self.entry.get()
if len(num) == 0:
self.answersbox.insert(0, "Please enter a number!\n")
elif int(num) > 100 or int(num) < 0 :
self.answersbox.insert(0, "You have to enter a number between 0 and 100!\n")
elif int(num) > self.actual_num:
self.answersbox.insert(0, "Too HIGH!\n")
elif int(num) < self.actual_num:
self.answersbox.insert(0, "Too LOW!\n")
elif int(num) == self.actual_num:
self.answersbox.insert(0, "Congratulations! The number was {}!\n".format(self.actual_num))
new_button = tk.Button(self.second_frame, bg="#CC8E1A", fg="#001F4C",
text="PLAY AGAIN!", font="Helvetica 13 bold", activebackground="#815B14",
cursor="hand2", padx=100, pady=10, relief="groove",
command=lambda: self.restart_game())
new_button.pack(pady=15)
self.entry.delete(0, tk.END)
def create_num(self):
return random.randint(0, 100)
def client_exit(self):
sys.exit("DONE!")
def restart_game(self):
self.main_frame.destroy()
self.second_frame.destroy()
self.cust_game()
root = tk.Tk()
app = GameWindow(root)
app.pack(fill="both", expand=True)
root.mainloop()
I am sorry if the code is too long to read. I've reached the point where, after the user guesses the number, he gets asked if he wants to play again, by pressing a Button
. I am thinking, that when the button gets pressed, the two frames (main_frame
and second_frame
) need to get deleted with the help of the command .destroy()
, but nothing seems to happen, when the button gets pressed. Please tell me what I'm doing wrong and if there's a better way to do this.
Upvotes: 0
Views: 128
Reputation: 26688
You can use tkMessageDialog
to ask user to play again:
import tkMessageBox
#... code
elif int(num) == self.actual_num:
self.answersbox.insert(0, "Congratulations! The number was {}!\n".format(self.actual_num))
if tkMessageBox.askyesno("Play", "play again?"):
self.answersbox.delete(0, END)
else:
sys.exit("DONE!")
Upvotes: 1
Reputation: 2134
When you click new_button
, restart_game
is called and the two frames are destroyed. They don't appear so because restart_game
then calls cust_game
which recreates the two frames.
Inserting a few print
s can help you understand the flow:
def cust_game(self):
self.main_frame = tk.Frame(self, bg="#8ECEBD")
self.main_frame.pack(fill="x")
print('main_frame created') # insert this
# ...
self.second_frame = tk.Frame(self, bg="#8ECEBD")
self.second_frame.pack(pady=30)
print('second_frame created') # insert this
def restart_game(self):
self.main_frame.destroy()
print('main_frame destroyed') # insert this
self.second_frame.destroy()
print('second_frame destroyed') # insert this
self.cust_game() # note cust_game is called
Then when you first start the game, it prints to the console:
main_frame created
second_frame created
And when you click to play again, it prints
main_frame destroyed
second_frame destroyed
main_frame created
second_frame created
BTW, command=lambda: f()
is superfluous. Just do command=f
; e.g., command=self.restart_game
.
Upvotes: 2