web-dev-qa-db-fra.com

tkinter: comment utiliser la méthode after

Hé, je suis nouveau sur python et utilise tkinter pour mon interface graphique. Je ne parviens pas à utiliser la méthode "après". Le but est de faire apparaître une lettre au hasard toutes les 5 secondes.

Voici mon code:

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

quelqu'un peut-il m'aider s'il vous plaît --- le problème est certainement frame.after (500): je ne suis pas sûr s'il est correct d'utiliser "frame" et je ne sais pas quel argument suit le 500.

Merci

26
user2456977

Vous devez donner une fonction à appeler après le délai comme deuxième argument de after :

after (delay_ms, callback = None, * args)

Enregistre un rappel d'alarme appelé après un certain temps.

Donc, ce que vous voulez vraiment faire, c'est ceci:

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

Vous devez également planifier la réappel de la fonction en répétant l'appel à after à l'intérieur de la fonction de rappel, car after n'exécute qu'une fois la fonction donnée. Ceci est également noté dans la documentation:

Le rappel n'est appelé qu'une fois pour chaque appel de cette méthode. Pour continuer à appeler le rappel, vous devez réenregistrer le rappel à l'intérieur de lui-même.

Notez que votre exemple lèvera une exception dès que vous aurez épuisé toutes les entrées de tiles_letter, vous devez donc modifier votre logique pour traiter ce cas comme vous le souhaitez. Le plus simple serait d’ajouter un chèque au début de add_letter pour vous assurer que la liste n’est pas vide et que return s’il le faut:

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
35
dano