Errror: _tkinter.TclError: bad window path name ".!button"

So today I tried to use python classes for the first time, to remove the excessive use of global keyword. I am trying to create a tkinter window in which, when we click one button it removes the clicked button and replaces it with a new button. And when we click it again, it removes this button and replaces the old (first) button and this should cycle through out…

This is my code which I made:

# ================= Importing Modules ===================
from tkinter import *
import tkinter as tk

# ====================================================
class Test():
 
    # ============= Play Button Click =============
    def fun1(self):
            self.hi.destroy()
            self.he.place(x=350,y=340)

    # ============ Pause Button Click =============
    def fun2(self):
            self.he.destroy()
            self.hi.place(x=350,y=340)
            
    # ============ Player Window ================
    def __init__(self):
        self.root = Tk()
        self.root.geometry('700x400')
        self.root.resizable(0,0)
        self.root["bg"] = "black"
        
        self.hi = tk.Button(self.root, text="button 1", bg="white", bd=0, command=lambda: self.fun1() , relief=RIDGE)
        self.hi.place(x=350,y=340)

        self.he = tk.Button(self.root, text="button 2", bg="white", bd=0,  command=lambda: self.fun2() , relief=RIDGE)
        self.root.mainloop()

# ============== Calling ===========

if __name__ == '__main__':
        Test()

    

But Instead of the desired output, sadly, I got this error:

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:/XXX/XXX/Desktop/test.py", line 29, in <lambda>
    self.he = tk.Button(self.root, text="button 2", bg="white", bd=0,  command=lambda: self.fun2() , relief=RIDGE)
  File "C:/XXX/XXX/Desktop/test.py", line 16, in fun2
    self.hi.place(x=350,y=340)
  File "C:\Program Files\Python310\lib\tkinter\__init__.py", line 2477, in place_configure
    self.tk.call(
_tkinter.TclError: bad window path name ".!button"

SO MY QUESTION IS:

doubt1 = Any idea what I am doing wrong?
doubt2 = Or isn't this possible?
if doubt1 or doubt2:
   Please explain it...
elif:
   Please tell me a better alternative or idea, how to do this efficiently.
else:
   Note: I have researched so many questions. Nothing helped me out. Especially ---|
                                                                                   ↓

ㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤthis one.

>Solution :

You’re destroying self.hi and then later trying to call place on the destroyed button. Once a widget has been destroyed you can no longer use it.

If you want to keep cycling the buttons, don’t destroy them. Since you are using place, you can use self.hi.place_forget() and self.he.place_forget() to remove the buttons from view without destroying them.

Leave a Reply