-1

This is the error i am having. Whenever i run the program everything runs smoothly but as soon as i close the GUI window the following error shows on my terminal. what should i doo to eliminate the problem

Exception in Tkinter callback
Traceback (most recent call last):
  File "C:\Program Files\Python310\lib\tkinter\__init__.py", line 1921, in __call__
    return self.func(*args)
  File "C:\Users\LENOVO\Desktop\notes thrd sem\project code\tkinter_tutorials\Player_vs_Computer.py", line 198, in click
    buttons[key - 1]["text"] = game_board[key]
  File "C:\Program Files\Python310\lib\tkinter\__init__.py", line 1686, in __setitem__
    self.configure({key: value})
  File "C:\Program Files\Python310\lib\tkinter\__init__.py", line 1675, in configure
    return self._configure('configure', cnf, kw)
  File "C:\Program Files\Python310\lib\tkinter\__init__.py", line 1665, in _configure
    self.tk.call(_flatten((self._w, cmd)) + self._options(cnf))
_tkinter.TclError: invalid command name ".!frame2.!label.!frame.!button"

the following is the code to a tic-tac-toe game that has an AI opponent that i implemented using the minimax algorithm. I also made a player vs player version but as soon as i implemented the algorithm the error mentioned above started popping up.

    from tkinter import *

import pygame

# global variables

turn = "O"
end_game = False
game_win_condition = True
global game_board

# initializing pygame sound**your text**

pygame.mixer.init()

# game board
game_board = {1: " ", 2: " ", 3: " ",
              4: " ", 5: " ", 6: " ",
              7: " ", 8: " ", 9: " "}


# defining functions
def computer_playing():
    bestScore = -100
    bestPosition = 0
    for key in game_board.keys():
        if (game_board[key] == " "):
            game_board[key] = "X"
            score = minimax(game_board, False)
            game_board[key] = " "
            if (score > bestScore):
                bestScore = score
                bestPosition = key
    game_board[bestPosition] = "X"


def minimax(game_board, isMaximizing):
    if (check_win("O")):
        return -1
    elif (check_win("X")):
        return 1
    elif (check_draw()):
        return 0
    elif isMaximizing:
        bestScore = -100
        for key in game_board.keys():
            if (game_board[key] == " "):
                game_board[key] = "X"
                score = minimax(game_board, False)
                game_board[key] = " "
                if (score > bestScore):
                    bestScore = score
        return bestScore
    else:
        bestScore = 100
        for key in game_board.keys():
            if (game_board[key] == " "):
                game_board[key] = "O"
                score = minimax(game_board, True)
                game_board[key] = " "
                if (score < bestScore):
                    bestScore = score
        return bestScore


def toplevel_window_win_message(player):
    global tp
    tp = Toplevel(Computer_root)
    tp_width = 240
    tp_height = 190
    tp.configure(borderwidth=5, relief="groove", bg="#567999")
    window_x = Computer_root.winfo_x()
    window_y = Computer_root.winfo_y()
    center_x = int((window_x) + (tp_width / 3.8))
    center_y = int((window_y) + (tp_height / 1.2))
    tp.geometry(f'{tp_width}x{tp_height}+{center_x}+{center_y}')
    tp.maxsize(tp_width, tp_height)
    tp.minsize(tp_width, tp_height)
    if (game_win_condition):
        win_message_label = Label(tp, text=player + " has won the game", font="Arial 15 bold ", bg="#567999",
                                  fg="white")
        win_message_label.pack(padx=15, pady=45)
    else:
        win_message_label = Label(tp, text="The game is a draw", font="Arial 15 bold ", bg="#567999", fg="white")
        win_message_label.pack(padx=15, pady=45)
    ok_button_frame = Frame(tp, borderwidth=1, bg="black")
    ok_button_frame.pack(padx=int((tp_width / 2) - 30), pady=int(tp_height - 190))
    ok_button = Button(ok_button_frame, text="OK", font="Arial 12", relief="raised", width=4, height=1, padx=10,
                       command=call_two_functions)
    ok_button.pack()
    tp.overrideredirect(True)
    tp.mainloop()


def call_two_functions():
    pygame.mixer.music.load("restart button sound.mp3")
    pygame.mixer.music.play()
    restart_button_function()
    tp.destroy()


def restart_game():
    global end_game
    for i in game_board.keys():
        game_board[i] = " "
    for i in buttons:
        i["text"] = " "
    pygame.mixer.music.load("restart button sound.mp3")
    pygame.mixer.music.play()
    end_game = False
    restart_button.destroy()
    frame12.destroy()


def check_draw():
    global game_win_condition
    for i in game_board.keys():
        if (game_board[i] == " "):
            return False
    game_win_condition = False
    return True


def check_win(player):
    global game_win_condition
    if (game_board[1] == game_board[2] == game_board[3] and game_board[3] == player):
        game_win_condition = True
        return True
    elif (game_board[1] == game_board[4] == game_board[7] and game_board[7] == player):
        game_win_condition = True
        return True
    elif (game_board[1] == game_board[5] == game_board[9] and game_board[9] == player):
        game_win_condition = True
        return True
    elif (game_board[2] == game_board[5] == game_board[8] and game_board[8] == player):
        game_win_condition = True
        return True
    elif (game_board[3] == game_board[6] == game_board[9] and game_board[9] == player):
        game_win_condition = True
        return True
    elif (game_board[4] == game_board[5] == game_board[6] and game_board[6] == player):
        game_win_condition = True
        return True
    elif (game_board[7] == game_board[8] == game_board[9] and game_board[9] == player):
        game_win_condition = True
        return True
    elif (game_board[3] == game_board[5] == game_board[7] and game_board[7] == player):
        game_win_condition = True
        return True
    else:
        return False


def click(event):
    global turn, end_game
    if (end_game):
        return
    else:
        button = event.widget

        # determining the position of the button clicked

        buttonlabel = str(button)
        buttonposition = buttonlabel[-9]
        if (buttonposition == "e"):
            buttonposition = 1
        else:
            buttonposition = int(buttonposition)

        # get input from the user , play the click sound

        if (button["text"] == " "):
            if (turn == "O"):
                button["text"] = "O"
                game_board[buttonposition] = turn
                pygame.mixer.music.load("alu_sound.mp3")
                pygame.mixer.music.play()

                # check win

                if (check_win(turn)):
                    end_game = True
                    pygame.mixer.music.load("Win windows sound.mp3")
                    pygame.mixer.music.play()
                    toplevel_window_win_message(turn)

                # check draw

                elif (check_draw()):
                    end_game = True
                    pygame.mixer.music.load("windows draw sound.mp3")
                    pygame.mixer.music.play()
                    toplevel_window_win_message(turn)
                turn = "X"

                computer_playing()
                for key in game_board.keys():
                    buttons[key - 1]["text"] = game_board[key]
                turn = "O"


# creating window

Computer_root = Tk()

window_width = 350
window_height = 482

screen_width = Computer_root.winfo_screenwidth()
screen_height = Computer_root.winfo_screenheight()

center_x = int((screen_width / 2) - (window_width / 2))
center_y = int((screen_height / 2) - (window_height / 2))

# window properties

Computer_root.title("Tic-Tac-Toe")
Computer_root.geometry(f'{window_width}x{window_height}+{center_x}+{center_y}')
Computer_root.minsize(window_width, window_height)
Computer_root.maxsize(window_width, window_height)
Computer_root["background"] = "#457bad"

# topic frame

frame1 = Frame(Computer_root, bg="black", borderwidth=2)
frame1.pack(pady=14)

label = Label(frame1, text="Tic-Tac-Toe", font="Arial 20")
label.grid()

# mainframe

frame2 = Frame(Computer_root, bg="black", borderwidth=3)
frame2.pack(pady=7)

# label -- inside this all the subframes and buttons are included

label1 = Label(frame2)
label1.grid()

# Subframe and buttons -- inside sub-frames are the buttons

# ROW 1
# BUTTON 1

frame3 = Frame(label1, bg="grey", borderwidth=2)
frame3.grid(row=0, column=0, padx=10, pady=10)

button1 = Button(frame3, text=" ", height=2, width=4, font="Arial 17", relief="raised")
button1.grid()
button1.bind("<Button-1>", click)

# BUTTON 2

frame4 = Frame(label1, bg="grey", borderwidth=2)
frame4.grid(row=0, column=1, padx=10, pady=10)

button2 = Button(frame4, text=" ", height=2, width=4, font="Arial 17", relief="raised")
button2.grid()
button2.bind("<Button-1>", click)

# BUTTON 3

frame5 = Frame(label1, bg="grey", borderwidth=2)
frame5.grid(row=0, column=2, padx=10, pady=10)

button3 = Button(frame5, text=" ", height=2, width=4, font="Arial 17", relief="raised")
button3.grid()
button3.bind("<Button-1>", click)

# ROW 2
# BUTTON 4

frame6 = Frame(label1, bg="grey", borderwidth=2)
frame6.grid(row=1, column=0, padx=10, pady=10)

button4 = Button(frame6, text=" ", height=2, width=4, font="Arial 17", relief="raised")
button4.grid()
button4.bind("<Button-1>", click)

# BUTTON 5

frame7 = Frame(label1, bg="grey", borderwidth=2)
frame7.grid(row=1, column=1, padx=10, pady=10)

button5 = Button(frame7, text=" ", height=2, width=4, font="Arial 17", relief="raised")
button5.grid()
button5.bind("<Button-1>", click)

# BUTTON 6

frame8 = Frame(label1, bg="grey", borderwidth=2)
frame8.grid(row=1, column=2, padx=10, pady=10)

button6 = Button(frame8, text=" ", height=2, width=4, font="Arial 17", relief="raised")
button6.grid()
button6.bind("<Button-1>", click)

# ROW 3
# BUTTON 7

frame9 = Frame(label1, bg="grey", borderwidth=2)
frame9.grid(row=2, column=0, padx=10, pady=10)

button7 = Button(frame9, text=" ", height=2, width=4, font="Arial 17", relief="raised")
button7.grid()
button7.bind("<Button-1>", click)

# BUTTON 8

frame10 = Frame(label1, bg="grey", borderwidth=2)
frame10.grid(row=2, column=1, padx=10, pady=10)

button8 = Button(frame10, text=" ", height=2, width=4, font="Arial 17", relief="raised")
button8.grid()
button8.bind("<Button-1>", click)

# BUTTON 9

frame11 = Frame(label1, bg="grey", borderwidth=2)
frame11.grid(row=2, column=2, padx=10, pady=10)

button9 = Button(frame11, text=" ", height=2, width=4, font="Arial 17", relief="raised")
button9.grid()
button9.bind("<Button-1>", click)


# Restart Button
def restart_button_function():
    global frame12
    frame12 = Frame(Computer_root, bg="black", borderwidth=2)
    frame12.pack(pady=14)

    global restart_button
    restart_button = Button(frame12, relief="raised", height=2, width=12, borderwidth=1, text="Restart Game",font="Arial 15", command=restart_game)
    restart_button.pack()


# buttons list

buttons = [button1, button2, button3, button4, button5, button6, button7, button8, button9]
# def update_computerinput():
#     for key in game_board.keys():
#         buttons[key-1]["text"]=game_board[key]

# event loop

Computer_root.mainloop()

desertnaut
  • 57,590
  • 26
  • 140
  • 166
  • That error almost always means you're trying to access a widget after it has been destroyed. In this case it means you're trying to change the text of a button that has been destroyed. – Bryan Oakley Aug 09 '23 at 16:20

0 Answers0