试图销毁按钮时出错

2021-05-13 14:02:49 发布

您现在位置:Python中文网/ 问答频道 /正文

问候语堆栈溢出!在

请注意,我是一个新手,我只是在学习。在

我有以下错误:AttributeError: '_tkinter.tkapp' object has no attribute 'button_draw'

问题所在的主要逻辑位于start_game_event。基本上,如果game_typewith draw,那么必须创建该按钮。但是,如果一个新的游戏是基于当前的窗口和按钮仍然存在,我希望它被删除。我不确定是否还有其他方法可以解决这个问题,比如完全重新生成主框架,但这正是我的立场。在

代码如下:

from tkinter import Button, E, Frame, IntVar, Label, LEFT, messagebox, N, NE, Radiobutton, RIGHT, S, SW, StringVar, Tk, Toplevel, W

class DominoWindow(Tk):

    def __init__(self):
        super().__init__()

        self.nb_players_var = None
        self.type_partie = None

        self.title('Jeu de Pydomino!')
        self.resizable(width=False, height=False)

        self.frame_player_north = Frame(self)
        self.frame_player_west = Frame(self)
        self.frame_table = Frame(self, borderwidth=2)
        self.frame_player_est = Frame(self)
        self.frame_current_player = Frame(self)

        self.frame_player_north.grid(row=0, column=1)
        self.frame_player_west.grid(row=1, column=0)
        self.frame_table.grid(row=1, column=1)
        self.frame_player_est.grid(row=1, column=2)
        self.frame_current_player.grid(row=2, column=1)

        self.label_name_player_north = Label(self.frame_player_north)
        self.label_name_player_north.grid(row=0)
        self.label_hand_player_north = Label(self.frame_player_north)
        self.label_hand_player_north.grid(row=1)

        self.label_name_player_west = Label(self.frame_player_west)
        self.label_name_player_west.grid(row=0)
        self.label_hand_player_west = Label(self.frame_player_west)
        self.label_hand_player_west.grid(row=1)

        self.label_table = Label(self.frame_table, height=8, width=100)
        self.label_table.grid(row=0, column=0)

        self.label_name_player_east = Label(self.frame_player_est)
        self.label_name_player_east.grid(row=0)
        self.label_hand_player_east = Label(self.frame_player_est)
        self.label_hand_player_east.grid(row=1)

        self.label_name_current_player = Label(self.frame_current_player)
        self.label_name_current_player.grid(row=1)
        self.frame_hand_current_player = Frame(self.frame_current_player)

        self.button_quit = Button(self, text="Quitter", command=self.quit_party_event)
        self.button_quit.grid(row=3, column=2)

        self.button_new_game = Button(self, text="Nouvelle partie", command=self.introduction_game)
        self.button_new_game.grid(row=2, column=2)

        self.introduction_game()

    def show(self):

        if self.nb_players_var.get() == 2:
            self.label_name_player_north.config(text="Player 0")
            self.label_hand_player_north.config(text="[|]" * 6) #len(self.partie.donnes[self.partie.tour+1]))

            self.label_table.config(text="VARIABLE_TABLE")
            self.label_name_current_player.config(text="Player Current")

            self.label_name_player_east.config(text="")
            self.label_hand_player_east.config(text="")
            self.label_name_player_west.config(text="")
            self.label_hand_player_west.config(text="")

        elif self.nb_players_var.get() == 3:
            self.label_name_player_north.config(text="Player 0")
            self.label_hand_player_north.config(text="[|]" * 6) #len(partie.Partie.donnes[partie.tour+1]))

            self.label_name_player_east.config(text="Player 1")
            self.label_hand_player_east.config(text="[|]\n" * 6) #len(self.partie.donnes[self.partie.tour+2]))

            self.label_table.config(text="VARIABLE DU PLATEAU")
            self.label_name_current_player.config(text="Player Current")

            self.label_name_player_west.config(text="")
            self.label_hand_player_west.config(text="")

        elif self.nb_players_var.get() == 4:
            self.label_name_player_north.config(text="Player 0")
            self.label_hand_player_north.config(text="[|]" * 6) #len(self.partie.donnes[self.partie.tour+1]))

            self.label_name_player_east.config(text="Player 1")
            self.label_hand_player_east.config(text="[|]\n" * 6) #len(self.partie.donnes[self.partie.tour+2]))

            self.label_name_player_west.config(text="Player 3")
            self.label_hand_player_west.config(text="[|]\n" * 6) #len(self.partie.donnes[self.partir.tour+3]))

            self.label_table.config(text="VARIABLE_DU_PLATEAU")
            self.label_name_current_player.config(text="Player Current")

    def introduction_game(self):
        self.introduction_window_game = Toplevel(self, height=200, width=500)
        self.introduction_window_game.title("Choose your game settings!")
        self.introduction_window_game._root().lift()
        self.nb_players_var = IntVar()
        self.type_partie = StringVar()
        # Label(self.introduction_window_game, text="Choose your game settings!").pack()
        Label(self.introduction_window_game, text="\nWhat kind of game do you want?").pack()
        Radiobutton(self.introduction_window_game, text="Game without draw",
                    variable=self.type_partie, value="without draw").pack(anchor=W)
        Radiobutton(self.introduction_window_game, text="Game with draw",
                    variable=self.type_partie, value="with draw").pack(anchor=W)

        Label(self.introduction_window_game, text="\nCombien de Players voulez-vous?").pack()
        Radiobutton(self.introduction_window_game, text="2 Players",
                    variable=self.nb_players_var, value=2).pack(anchor=W)
        Radiobutton(self.introduction_window_game, text="3 Players",
                    variable=self.nb_players_var, value=3).pack(anchor=W)
        Radiobutton(self.introduction_window_game, text="4 Players",
                    variable=self.nb_players_var, value=4).pack(anchor=W)

        Button(self.introduction_window_game, text="Quit",
               command=self.quit_party_event).pack(side=RIGHT)
        Button(self.introduction_window_game, text="Ok",
               command=self.start_game_event).pack(side=RIGHT)

    def start_game_event(self):
        result = messagebox.askokcancel("Paramètres de partie",
                                        f"Vous avez choisi {self.nb_players_var.get()} Players et "
                                        f"le type de partie {self.type_partie.get()}."
                                        f"\nEst-ce exact?", icon='warning')
        if result == True:
            self.start_game()
            self.show()
            self.introduction_window_game.destroy()
            if self.type_partie.get() == "with draw":
                self.button_draw = Button(self, text="Draw", command=self.button_to_draw)
                self.button_draw.grid(row=3, column=0)
            else:
                self.button_draw.grid_remove()
                self.destroy

    def quit_party_event(self):
        result = messagebox.askokcancel("Quit the game.", "Are you sur?", icon='warning')
        if result == True:
            self.destroy()

    def button_to_draw(self):
        print("Function test. You drew a domino!")

    def message_fin_de_partie(self):
        pass

if __name__ == '__main__':
    DominoWindow().mainloop()

错误位于此处:self.button_draw.grid_remove()

谢谢你,希望一切都清楚。在

已编辑:删除依赖项并调整变量名。打错了。在

1条回答
网友
1楼 ·

我先说我注释掉了self.start_game()行,因为start_game方法不存在。我还要补充一点,为了重现这个问题,我启动了这个应用程序,然后选择了在没有任何数量玩家的情况下开始游戏。在

最终你可以做你想做的事情:也就是说,不要总是按“绘制”按钮。我要做的是在__init__()内的某处添加self.button_draw = None行。这样可以确保窗口始终具有一个button_draw属性,从而消除了关于该属性的AttributeError。在

下一步,您需要调整if中较低的if语句,以便从网格中删除已创建的“Draw”按钮:

        if self.type_partie.get() == "with draw":
            self.button_draw = Button(self, text="Draw", command=self.button_to_draw)
            self.button_draw.grid(row=3, column=0)
        elif self.button_draw is not None:
            self.button_draw.grid_remove()
            self.button_draw.destroy()
            self.button_draw = None

我用else替换了elif,并且self.button_draw不是{}的条件:如果没有按钮可以删除,我们就不能删除'Draw'按钮。在

还请注意,我将self.destroy替换为self.button_draw.destroy():如果你调用了这个方法,前者会关闭你的应用程序,但是由于你没有调用self.desroy,它什么也没有做。此外,一旦按钮被破坏,我们可以将self.button_draw设置回None,以表示我们没有“绘制”按钮。在

类似地,如果“Draw”按钮存在并且你用Draw开始另一个游戏,你的窗口中会有两个按钮。你只能看到一个,因为一个在另一个上面。但是,由于您只保留对一个按钮的引用,因此只能删除这两个按钮中的一个。如果按钮不存在,我将留给您对代码进行类似的修改,以便只添加按钮。在

相关问题