In my Tkinter program, this program is intended to render 3 squares in the canvas, and change their color every second. I want this change to occur every second 100 times.
It works, as logging the current color will get printed in the terminal as expected, but when I introduce the sleep() method it causes the canvas to not load.
Any suggestions here?
from tkinter import messagebox
import time
top = Tk()
C = Canvas(top, bg="white", height=300, width=400)
coord1 = 30, 10, 120, 80
coord2 = 150, 10, 240, 80
coord3 = 270, 10, 370, 80
colors = ['red', 'green', 'blue']
for i in range(0,100):
for x in range(0,3):
C.create_rectangle(coord1, fill=colors[x])
C.create_rectangle(coord2, fill=colors[x])
C.create_rectangle(coord3, fill=colors[x])
print(colors[x])
# time.sleep(1)
C.pack()
top.mainloop()
>Solution :
When using time.sleep(), the entire program is going to be paused, including the Tkinter event loop. This is why the canvas wouldn’t be loading or updating as expected.
To fix this you should use the .after() method of Tkinter. The method schedules a function to be called after a given amount of time (https://www.pythontutorial.net/tkinter/tkinter-after/). Using .after() allows you to create a delay without freezing the Tkinter GUI.
Here is what your updated code should look like:
from tkinter import Tk, Canvas
import itertools
def change_color():
color = next(color_cycle)
C.itemconfig(rect1, fill=color)
C.itemconfig(rect2, fill=color)
C.itemconfig(rect3, fill=color)
print(color)
if change_color.counter < 100:
top.after(1000, change_color) # Schedule next color change after 1000ms
change_color.counter += 1
top = Tk()
C = Canvas(top, bg="white", height=300, width=400)
coord1 = 30, 10, 120, 80
coord2 = 150, 10, 240, 80
coord3 = 270, 10, 370, 80
colors = ['red', 'green', 'blue']
color_cycle = itertools.cycle(colors)
# Create rectangles and store their references
rect1 = C.create_rectangle(coord1, fill="")
rect2 = C.create_rectangle(coord2, fill="")
rect3 = C.create_rectangle(coord3, fill="")
C.pack()
change_color.counter = 0 # Initialize counter for the number of changes
change_color() # Start changing colors
top.mainloop()
The change_color function is defined to change color of the rectangles and then schedule itself to be called again every 1000milliseconds (1 second).
Let me know if you have any more questions about this.