Event driven programming requires a different approach to the process code. Your application runs in an endless loop, pulling events from the queue and processing them. To make an animation, all you have to do is place the elements in this queue at the appropriate time.
Tkinter widgets have a method called after , which allows you to schedule the execution of functions after a certain period of time. The first step is to write a function that takes one βframeβ of your animation. In your case, you define an animation as a transition between two colors. A function that checks the current color, then switches to a different color, all you need is:
def blink(rect, canvas): current_color = canvas.itemcget(rect, "fill") new_color = "red" if current_color == "white" else "white" canvas.itemconfigure(rect, fill=new_color)
Now we just need this function to be executed three times with an interval of one second:
root.after(1000, blink, rect, canv) root.after(2000, blink, rect, canv) root.after(3000, blink, rect, canv)
When you start your main cycle, after one second the color will change, after a second it will change again, and after a third second it will change again.
This works for your specific need, but it is not a good general solution. A more general solution is to call blink once, and then blink again to call itself after a period of time. blink then should be responsible to know when to stop blinking. You can set a flag or counter to keep track of how many times you blinked. For instance:
def blink(rect, canvas): ...
As a final tip, I recommend that you define your program as a class, and then instantiate this class. This makes it so that you do not need global functions, and you do not need to pass as many arguments. It doesn't really matter for a 20-line program, but it starts to matter if you want to write something significant.
For instance:
from tkinter import * class MyApp(Tk): def __init__(self): Tk.__init__(self) fr = Frame(self) fr.pack() self.canvas = Canvas(fr, height = 100, width = 100) self.canvas.pack() self.rect = self.canvas.create_rectangle(25, 25, 75, 75, fill = "white") self.do_blink = False start_button = Button(self, text="start blinking", command=self.start_blinking) stop_button = Button(self, text="stop blinking", command=self.stop_blinking) start_button.pack() stop_button.pack() def start_blinking(self): self.do_blink = True self.blink() def stop_blinking(self): self.do_blink = False def blink(self): if self.do_blink: current_color = self.canvas.itemcget(self.rect, "fill") new_color = "red" if current_color == "white" else "white" self.canvas.itemconfigure(self.rect, fill=new_color) self.after(1000, self.blink) if __name__ == "__main__": root = MyApp() root.mainloop()