Hola, soy nuevo en Python y estoy usando tkinter para mi interfaz gráfica de usuario. Tengo problemas para usar el método “después”. El objetivo es hacer que aparezca una letra al azar cada 5 segundos.
Aquí está mi código:
import random
import time
from tkinter import *
root = Tk()
w = Label(root, text="GAME")
w.pack()
frame = Frame(root, width=300, height=300)
frame.pack()
L1 = Label(root, text="User Name")
L1.pack(side=LEFT)
E1 = Entry(root, bd =5)
E1.pack(side=LEFT)
tiles_letter = ['a', 'b', 'c', 'd', 'e']
while len(tiles_letter) > 0:
rand = random.choice(tiles_letter)
tile_frame = Label(frame, text=rand)
tile_frame.pack()
frame.after(500)
tiles_letter.remove(rand) # remove that tile from list of tiles
root.mainloop()
¿Puede alguien ayudarme? El problema es definitivamente frame.after (500): no estoy seguro de si es correcto usar “frame” y no sé qué argumento sigue al 500.
Gracias
Debe dar una función para llamar después del retraso de tiempo como segundo argumento para after
:
after(delay_ms, callback=None, *args)
Registra una devolución de llamada de alarma que se llama después de un tiempo determinado.
Así que lo que realmente quieres hacer es esto:
tiles_letter = ['a', 'b', 'c', 'd', 'e']
def add_letter():
rand = random.choice(tiles_letter)
tile_frame = Label(frame, text=rand)
tile_frame.pack()
root.after(500, add_letter)
tiles_letter.remove(rand) # remove that tile from list of tiles
root.after(0, add_letter) # add_letter will run as soon as the mainloop starts.
root.mainloop()
También debe programar la función para que se vuelva a llamar repitiendo la llamada a after
dentro de la función de devolución de llamada, ya que after
solo ejecuta la función dada una vez. Esto también se indica en la documentación:
La devolución de llamada solo se llama una vez por cada llamada a este método. Para seguir llamando a la devolución de llamada, debe volver a registrar la devolución de llamada dentro de sí misma
Tenga en cuenta que su ejemplo arrojará una excepción tan pronto como haya agotado todas las entradas en tiles_letter
, por lo que debe cambiar su lógica para manejar ese caso de la forma que desee. Lo más sencillo sería añadir un cheque al principio de add_letter
para asegurarse de que la lista no esté vacía, y simplemente return
si esto es:
def add_letter():
if not tiles_letter:
return
rand = random.choice(tiles_letter)
tile_frame = Label(frame, text=rand)
tile_frame.pack()
root.after(500, add_letter)
tiles_letter.remove(rand) # remove that tile from list of tiles
Demo en vivo: repl.it
Creo que los 500 ms se ejecutan en segundo plano, mientras que el resto del código continúa ejecutándose y vacía la lista.
Luego, después de 500 ms, no sucede nada, ya que no se implementa ninguna llamada de función en la llamada posterior (igual que frame.after(500, function=None)
)