_tkinter.tclerror: Can't Invoke "update" Command: Application Has Been Destroyed Error
Solution 1:
I agree with the others that you should be using mainloop()
here however if you would like to keep the original code the way I would do this is keep track of a boolean and do while x == True
instead. This way we can update the value of x to equal False
and this should keep the error from happening.
We can use the protocol()
method to update our boolean when the app closes.
If we add this to your code:
x = Truedefupdate_x():
global x
x = False
tk.protocol("WM_DELETE_WINDOW", update_x)
And change your while statement to:
while x == True:
tk.update_idletasks()
tk.update()
time.sleep(0.01)
So your full code might look like this:
from tkinter import *
import random
import time
tk=Tk()
tk.title("My 21st Century Pong Game")
tk.resizable(0,0)
tk.wm_attributes("-topmost",1)
x = Truedefupdate_x():
global x
x = False
tk.protocol("WM_DELETE_WINDOW", update_x)
canvas=Canvas(tk,bg="white",width=500,height=400,bd=0,highlightthickness=0)
canvas.pack()
tk.update()
classBall:
def__init__(self,canvas,color):
self.canvas=canvas
self.id=canvas.create_oval(30,30,50,50,fill=color)
""" Note: x and y coordinates for top left corner and x and y coordinates for the bottom right corner, and finally the fill colour for the oval
"""
self.canvas.move(self.id,0,0)
defdraw(self):
pass
ball1=Ball(canvas,'green')
while x == True:
tk.update_idletasks()
tk.update()
time.sleep(0.01)
This will fix your problem.
To reiterate what others have said all you really need is the mainloop()
here and not your while i:
statement.
The mainloop()
method is used to be the reset on the loop for your instance of Tk()
Once the code reaches the line that says tk.mainloop()
then it will being the next loop of your code.
The proper way to write your code is to just use mainloop()
as it does all the updating for a tkinter instance.
See below code using mainloop()
:
from tkinter import *
tk=Tk()
tk.title("My 21st Century Pong Game")
tk.resizable(0,0)
tk.wm_attributes("-topmost",1)
canvas=Canvas(tk,bg="white",width=500,height=400,bd=0,highlightthickness=0)
canvas.pack()
tk.update()
classBall:
def__init__(self,canvas,color):
self.canvas=canvas
self.id=canvas.create_oval(30,30,50,50,fill=color)
""" Note: x and y coordinates for top left corner and x and y coordinates for the bottom right corner, and finally the fill colour for the oval
"""
self.canvas.move(self.id,0,0)
defdraw(self):
pass
ball1=Ball(canvas,'green')
tk.mainloop()
Solution 2:
You are effectively trying to implement your own mainloop
instead of using it.
To understand the mainloop
, you can read about it here. You can think of it as a syntactical abstraction of the new code you added; your while
loop. You are almost trying to recreate the wheel by making your own loop to "update the screen", when one already exists!
When exiting the program, you could avoid errors by using sys.exit()
.
Edit:
Replace the following code:
while 1:
tk.update_idletasks()
tk.update()
time.sleep(0.01)
With this:
tk.mainloop()
Your error is because, as it says, you cannot update the window if it has been destroyed. The mainloop
should handle this.
Solution 3:
When you exit your app, the next time you call update_idletasks
the window object is destroyed. You then try to call update
on a window that doesn't exist.
You need to remove all four lines starting with while
and replace them with the single line tk.mainloop()
which properly handles the destruction of the window.
Also, in case you are tempted to keep your original code, there is no reason to call both update_idletasks
and update
. The former is a subset of the latter.
Post a Comment for "_tkinter.tclerror: Can't Invoke "update" Command: Application Has Been Destroyed Error"