1

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"
j_4321
  • 15,431
  • 3
  • 34
  • 61
Brian Tiong
  • 21
  • 1
  • 1
  • 3
  • 3
    do not attach image of the code . place it here – Tejas Pandya Dec 18 '17 at 07:12
  • 1
    use `tkintet.after()` instead of `while` – furas Dec 18 '17 at 08:12
  • 1
    `IDLE` is built with `tkinter` so sometimes it makes problem with code which use `tkinter`. Run code in console/terminal/cmd.exe to test it. – furas Dec 18 '17 at 08:14
  • Possible duplicate of [\_tkinter.TclError: invalid command name ".4302957584"](https://stackoverflow.com/questions/16059592/tkinter-tclerror-invalid-command-name-4302957584) – Nae Dec 18 '17 at 11:39

2 Answers2

2

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()
Nae
  • 14,209
  • 7
  • 52
  • 79
  • Using `after(0, ...)` is a bad idea. The first argument ought to be at least 1 (one)` otherwise you might prevent any other events from being processed. Also, you can remove the call to `update_idletasks()` if you make that change. – Bryan Oakley Dec 18 '17 at 12:52
  • @BryanOakley I tried using 1 but discarded that as it looked slower than the OP's animation. Then again one could tweak that using `t` I guess. – Nae Dec 18 '17 at 12:54
  • I haven't run it, but I'd go with @Nae's second suggestion (with Bryan Oakley's suggestion). Much more elegant. Unless you really don't care (since the error doesn't really effect anything as it happens after the application is closed. Then I'd just call it a day with a try except ;-) +1 for Nae from me – zlmonroe Dec 18 '17 at 21:21
0

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.

zlmonroe
  • 330
  • 1
  • 3
  • 10
  • Ya, that error confused me a lot. Everything is fine while running but end up with error. But if I add "pai.mainloop()" as you said, the error is still going. – Brian Tiong Dec 18 '17 at 08:20
  • 1
    the pai.mainloop() was not to fix the error, just a general suggestion. The error comes from the fact that it terminated while still running. In my opinion, it isn't too big of an error. If you want to fix it, you could catch it with a try, except block. The mainloop has to do with you programs being able to handle events. Your program doesn't suffer much from the lack of it, but it is a good practice to have it. (I've forgotten and been rather confused to not have my events work) – zlmonroe Dec 18 '17 at 08:32