Reputation: 21
I designed an arc which can rotate, but I can't figure out why IDLE tells me there is still an error in my code.
Here is my code:
from Tkinter import*
from math import *
from time import sleep
pai=Tk()
cv=Canvas(pai,width=1100,height=631,bg="white")
cv.pack()
bb=(150,110,550,510)
temp1=0
temp2=24
t=0
arc1=cv.create_arc(bb,start=temp1,extent=temp2,fill="yellow")
while True:
t=0.51
temp1+=t
cv.itemconfig(arc1,start=temp1)
cv.update()
And this is the results:
Traceback (most recent call last):
File "C:\Users\amazi\Desktop\作业\s.py", line 15, in <module>
cv.itemconfig(arc1,start=temp1)
File "C:\Python27\lib\lib-tk\Tkinter.py", line 2408, in itemconfigure
return self._configure(('itemconfigure', tagOrId), cnf, kw)
File "C:\Python27\lib\lib-tk\Tkinter.py", line 1321, in _configure
self.tk.call(_flatten((self._w, cmd)) + self._options(cnf))
TclError: invalid command name ".93591304L"
Upvotes: 1
Views: 12226
Reputation: 15315
I believe you're getting that error because you're trying to access widgets while there's none, similar to this question. When you close the application with x button, while True
loop tries to run at least once more on widgets that doesn't exist, thus produces an error. If you close the application by closing the command prompt, no error is produced as, where should it appear? Try the below example that animates exactly the way you'd want but without a while True
loop, which is not easily used along tkinter anyway:
import tkinter as tk
root = tk.Tk()
cv = tk.Canvas(root, width=1100, height=631, bg='white')
cv.pack()
bb = (150,110,550,510)
temp1 = 0
temp2 = 24
arc1=cv.create_arc(bb, start=temp1, extent=temp2, fill='yellow')
def rotate():
global temp1
t = 0.51
temp1 = (temp1 + t) % 360
print(temp1)
cv.itemconfig(arc1,start=temp1)
cv.update_idletasks()
cv.after(0, rotate)
cv.after(0, rotate)
root.mainloop()
Using Bryan's suggestion below another example may be produced. You may need to tweak t
in below example though:
import tkinter as tk
root = tk.Tk()
cv = tk.Canvas(root, width=1100, height=631, bg='white')
cv.pack()
bb = (150,110,550,510)
temp1 = 0
temp2 = 24
arc1=cv.create_arc(bb, start=temp1, extent=temp2, fill='yellow')
def rotate():
global temp1
t = 1
temp1 = (temp1 + t) % 360
print(temp1)
cv.itemconfig(arc1,start=temp1)
cv.after(1, rotate)
rotate()
root.mainloop()
Upvotes: 2
Reputation: 360
It seems to me that your code runs fine while it's running -- it's just ending it that is the problem. Did it give that error when you closed the application?
I modified the while True:
block to for i in range(500):
to verify this and as long as your loop doesn't expect to continue it closes perfectly.
Here are two possible ways you could fix this:
The easy way, catch the error:
from Tkinter import*
pai=Tk()
cv=Canvas(pai,width=1100,height=631,bg="white")
cv.pack()
bb=(150,110,550,510)
temp1=0
temp2=24
t=0
arc1=cv.create_arc(bb,start=temp1,extent=temp2,fill="yellow")
while True:
t=0.51
temp1+=t
try:
cv.itemconfig(arc1,start=temp1)
cv.update()
except TclError:
pass
pai.mainloop()
The hard way, don't make the error happen (give the gui a second to catch up):
import Tkinter as tk
def on_closing():
pai.cont = False
pai = tk.Tk()
pai.protocol("WM_DELETE_WINDOW", on_closing)
cv = tk.Canvas(pai,width=1100,height=631,bg="white")
cv.pack()
bb = (150,110,550,510)
temp1 = 0
temp2 = 24
t = 0
arc1 = cv.create_arc(bb,start=temp1,extent=temp2,fill="yellow")
pai.cont = True
while pai.cont:
t=0.51
temp1+=t
cv.itemconfig(arc1,start=temp1)
cv.update()
pai.destroy()
Personally though, while I don't usually suggest catching errors, I wouldn't go with the second option. Essentially what I'm doing there is creating a variable that tells the while loop whether it should continue or not, then when you click the close button updating that while to end. The infinite while loop is the main problem here in my opinion. Once it ends and the GUI can finish, it all works out.
Upvotes: 0