Simple animation with Tkinter Python
Question: I've searched for a simple animation code with Tkinter but I've found very
different examples and I can't understand the correct way to write an
animation. Here my working code to display a simple moving circle:

    
    
    import tkinter as tk
    import time
    
    root=tk.Tk()
    canvas=tk.Canvas(root,width=400,height=400)
    canvas.pack()
    circle=canvas.create_oval(50,50,80,80,outline="white",fill="blue")
    
    def redraw():
       canvas.after(100,redraw)
       canvas.move(circle,5,5)
       canvas.update()
    canvas.after(100,redraw)
    root.mainloop()
    

In this code I can't correctly understand: how the after method works, where
correctly put the update and the move method (before after method ?), is there
another way to write an animation code? may you post me another example and
comment the code please? Thanks :)


Answer: **Calling`update`**

You should not call `canvas.update()`. As a general rule of thumb you should
_never_ call `update`.

if you take out the call to `canvas.update()`, you have the proper way to do
animation in a tkinter program.

**Calling`after` to start the animation**

You don't need to call `after` immediately before calling `root.mainloop()`.
This works just as well:

    
    
    ...
    redraw()
    root.mainloop()
    

The choice to use or not use `after` in this specific case is dependent on if
you want the animation to start immediately (possibly even before the widget
is visible) or if you want it to happen after a short delay (possibly after
the widget is made visible)

**How`after` works**

`mainloop` is nothing more than an infinite loop that checks the event queue
for events. When it finds an event, it pops it off of the list and processes
it. `after` is nothing more than making a request that says "in 100 ms, please
add a new event to the queue". When the time limit expires, an event is added
to the queue that says, in effect, "run this command". The next time the loop
checks for events, it sees this event, pulls it off of the queue, and runs the
command.

When you call `after` from within a method that itself was called by `after`,
you're saying in effect "wait 100ms and do it again", creating an infinite
loop. If you put the call to `after` before moving the object, you're saying
"every 100ms run this function". If you put it after you're saying "run this
function 100 ms after the last time it was run". The difference is very subtle
and usually not perceptible unless your function takes a long time to run.

