Il ne faut pas oublier d'associer les fonctions
start()
et stop()
aux
boutons correspondants. Si votre fonction
start
est différente de celle
ci-dessous, elle n'est peut-être pas fausse.
Jetez un coup d'oeil à la solution.
##----- Fonctions réceptionnant les événements -----##
def stop():
"""Cette fonction baisse le drapeau et arrête l'animation."""
global drapeau
drapeau = False
def start():
"""Cette fonction lève le drapeau et lance l'animation."""
global drapeau
drapeau = True
move()
##----- Fonction générale pilotant les déplacements -----##
def move():
""" Entrées : Fonction déclenchée par le bouton [Démarrer]- pas d'entrée
Sorties : Fonction récursive qui redéfinit les coordonnées du centre
du cercle toutes les 30 ms, à condition que le drapeau soit levé"""
global x0, y0, dx, dy, l, r
x0 = x0+dx # Nouvelle abscisse du centre du cercle
dessin.coords(cercle, x0-r, y0-r, x0+r, y0+r)
if x0 >= l-r or x0 <= r: # Bord droit ou bord gauche atteint,
dx = -dx # le déplacement s'effectue dans l'autre sens
if drapeau:
fen.after(30, move)
Si le cercle accélère, c'est la fonction
start
qui est en cause. En effet,
lorsqu'on clique sur le bouton [Démarrer],
on appelle à nouveau une instance de la fonction
move()
qui est récursive. Il y a donc
empilement des appels donc déplacement plus rapide
du cercle à l'écran : ses coordonnées sont recalculées
plus souvent.
##----- Importation des Modules -----##
from tkinter import *
##----- Variables globales et conditions initiales -----##
l, h = 242, 242 # Dimensions du canevas
dx, dy = 5, 0 # "pas" initial du déplacement
x0, y0 = l//2, h//2 # Coordonnées initiales du cercle
r = 10 # Rayon du cercle
drapeau = False
##----- Fonction générale pilotant les déplacements -----##
def move():
""" Entrées : Fonction déclenchée par le bouton [Démarrer]- pas d'entrée
Sorties : Fonction récursive qui redéfinit les coordonnées du centre
du cercle toutes les 30 ms, à condition que le drapeau soit levé"""
global x0, y0, dx, dy, l, r
x0 = x0+dx # Nouvelle abscisse du centre du cercle
dessin.coords(cercle, x0-r, y0-r, x0+r, y0+r)
if x0 >= l-r or x0 <= r: # Bord droit ou bord gauche atteint,
dx = -dx # le déplacement s'effectue dans l'autre sens
if drapeau:
fen.after(30, move)
##----- Fonctions réceptionnant les événements -----##
def stop():
"""Cette fonction baisse le drapeau et arrête l'animation."""
global drapeau
drapeau = False
def start():
"""Cette fonction lève le drapeau et lance l'animation."""
global drapeau
if drapeau == False: # Nécessaire pour ne pas lancer plusieurs fois l'animation
drapeau = True
move()
##----- Création de la fenêtre -----##
fen = Tk()
fen.title('Balle qui rebondit')
##----- Création des boutons -----##
bouton_quitter = Button(fen, text="Quitter", width=9, command=fen.destroy)
bouton_quitter.grid(row = 1, column = 2, padx=3, pady=3)
bouton_stop = Button(fen, text="Arrêter", width=9, command=stop)
bouton_stop.grid(row = 1, column = 1, padx=3, pady=3)
bouton_start = Button(fen, text="Démarrer", width=9, command=start)
bouton_start.grid(row = 1, column = 0, padx=3, pady=3)
##----- Création du canevas -----##
dessin = Canvas(fen, bg="white", width=l, height=h)
dessin.grid(row = 0, column = 0, columnspan = 3, padx=3, pady=3)
##----- Objets graphiques -----##
cercle = dessin.create_oval(x0-r, y0-r, x0+r, y0+r, width=2, outline="red")
##----- Programme principal -----##
move()
fen.mainloop() # Boucle d'attente des événements