0

I've written a tkinter script with animation, that works fine on Xubuntu, but when I run it on Mac, the animation doesn't work. Here's a little script that demonstrates the problem:

import tkinter as tk
from time import sleep

root = tk.Tk()
canvas = tk.Canvas(root, height=200, width = 200)
canvas.pack()

this = canvas.create_rectangle(25,25, 75, 75, fill='blue')
that = canvas.create_rectangle(125, 125, 175, 175, fill = 'red')

def blink(event):
    global this, that
    for _ in range(9):
        canvas.itemconfigure(this, fill='red')
        canvas.itemconfigure(that, fill = 'blue')
        canvas.update_idletasks()
        sleep(.4)
        this, that = that, this
        
canvas.bind('<ButtonRelease-1>', blink)

root.mainloop()

This draws a red square and a blue square on a canvas. When the user clicks the canvas, the squares repeatedly switch colors. On Xubuntu, it works as intended.

On Mac, when I click the canvas, I get spinning beach ball, and after a few seconds, we see that squares have switched colors, because they switch colors an odd number of times in the code.

It seems to me that update_idletasks isn't working. Is there some way to fix this? I am running python 3.9.5 with Tk 8.6 on Big Sur.

saulspatz
  • 5,011
  • 5
  • 36
  • 47

2 Answers2

1

I think what you can do is avoid tasks that will block the mainloop, in this case time.sleep(). So your code can be remade by emulating a for loop with after, and I see nothing that stops this general code from running OS independent:

count = 0 # Think of this as the `_` in for _ in range(9)
def blink(event=None):
    global this, that, count
    
    if count < 9: # Basically repeats everytime `count` is less than 9, like a for loop
        canvas.itemconfigure(this, fill='red')
        canvas.itemconfigure(that, fill='blue')

        this, that = that, this
        count += 1 # Increase count
        root.after(400,blink) # Repeat this code block every 400 ms or 0.4 seconds
    else: 
        count = 0 # After it is 9, set it to 0 for the next click to be processed
Delrius Euphoria
  • 14,910
  • 3
  • 15
  • 46
0

I found that using update instead of update_idletasks works on both platforms. It's my understanding though, that the latter is much preferred. See the accepted answer to this question for example. This solves my immediate problem, but does anyone know if update_idletasks ever works on the Mac?

saulspatz
  • 5,011
  • 5
  • 36
  • 47