简体   繁体   English

PYTHON TKINTER-破坏框架

[英]PYTHON TKINTER - destroying frames

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. 我正在尝试使用tkinter构建一个“数字猜猜游戏”,您需要在其中通过在Entry小部件中输入它来猜测计算机生成的数字。

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 . 我已经到达了要点,在用户猜出数字之后,可以通过按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. 我在想,当按下按钮时,需要在命令.destroy()的帮助下删除两个帧( main_framesecond_frame .destroy() ,但是当按下按钮时似乎什么也没发生。 Please tell me what I'm doing wrong and if there's a better way to do this. 请告诉我我在做什么错,以及是否有更好的方法可以做到这一点。

When you click new_button , restart_game is called and the two frames are destroyed. 当您单击new_buttonrestart_game被称为和两帧破坏。 They don't appear so because restart_game then calls cust_game which recreates the two frames. 它们不会出现,是因为restart_game然后调用cust_game它再现了两个框架。

Inserting a few print s can help you understand the flow: 插入一些print可以帮助您理解流程:

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. 顺便说一句, command=lambda: f()是多余的。 Just do command=f ; 只需执行command=f ; eg, command=self.restart_game . 例如, command=self.restart_game

You can use tkMessageDialog to ask user to play again: 您可以使用tkMessageDialog要求用户再次播放:

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!")

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM