es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

¿Cómo puedo hacer que udate_idletasks funcione en Mac?

He escrito un script tkinter con animación que funciona bien en Xubuntu, pero cuando lo ejecuto en Mac, la animación no funciona. Aquí hay un pequeño script que muestra el problema:

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()

Esto dibuja un cuadrado rojo y un cuadrado azul en un lienzo. Cuando el usuario hace clic en el lienzo, los cuadrados cambian de color repetidamente. En Xubuntu, funciona como se esperaba.

En Mac, cuando hago clic en el lienzo, aparece la bola de playa giratoria y después de unos segundos, vemos que los cuadrados han cambiado de color, porque cambian de color un número impar de veces en el código.

Me parece que update_idletasks no está funcionando. ¿Hay alguna forma de solucionar esto? Estoy ejecutando Python 3.9.5 con Tk 8.6 en Big Sur.

Tags:  ,

Answer

  1. Avatar for davy.ai

    Es posible que el problema esté relacionado con la versión específica de Tkinter que está instalada en tu Mac, o con la compatibilidad entre Tkinter y Big Sur.

    Una posible solución es intentar utilizar el método after() en lugar de sleep() y update_idletasks(). El método after() programa una función para que se llame después de que haya transcurrido una cierta cantidad de tiempo, lo cual puede ayudar a evitar el bloqueo de la interfaz gráfica. Así es cómo podrías modificar la función blink para utilizar after() en su lugar:

    def blink(event):
        global this, that
        for _ in range(9):
            canvas.itemconfigure(this, fill='red')
            canvas.itemconfigure(that, fill='blue')
            canvas.after(400)
            this, that = that, this
    

    Esto hará que los cuadrados cambien de color cada 400 milisegundos, sin bloquear la interfaz gráfica.

    Si eso no funciona, otra opción es intentar instalar una versión diferente de Tkinter. Puedes verificar qué versiones de Tkinter están instaladas en tu Mac con el siguiente comando:

    python3 -m tkinter
    

    Esto mostrará una lista de las versiones de Tcl/Tk disponibles. Puedes intentar seleccionar una versión diferente configurando las variables de entorno TCL_LIBRARY y TK_LIBRARY antes de ejecutar tu script, de la siguiente manera:

    export TCL_LIBRARY=/ruta/a/otra/biblioteca/tcl
    export TK_LIBRARY=/ruta/a/otra/biblioteca/tk
    python3 tu_script.py
    

    Reemplaza /ruta/a/otra/biblioteca/tcl y /ruta/a/otra/biblioteca/tk con las rutas de las bibliotecas Tcl y Tk que desees utilizar. Es posible que necesites experimentar con diferentes versiones para encontrar una que funcione correctamente con tu script.

Comments are closed.