Simulation Partie I Chapitre 4 : Graphique en Python
précédent : solutions du chapitre 2 (Python en mode texte)
 
Nous savons calculer en Python et imprimer les résultats.
Pour étudier les fonctions f(x), il serait plus intéressant de faire des sorties graphiques.
Et ensuite des animations pour les résultats qui dépendent du temps :
en maths : courbes paramétriques
en physique : tous les problèmes évolutifs
Pour cela nous allons utiliser le "package" (ou module) qui s'appelle : "simplegui"
Un package contient des fonctions spécialisées qui ne sont pas utiles dans la plupart des cas.
C'est pour cela que ces fonctions ne sont pas accessibles en temps normal: Il faut les demander.
Ouvrez le site https://py3.codeskulptor.org dans une nouvelle fenêtre.
# chargement des fonctions du package simplegui
# GUI = Graphical User Interface
import simplegui

# affichage du contenu de simplegui :
for fonction in dir(simplegui) :
    print(fonction)
permet de charger toutes les fonctions graphiques dont nous aurons besoin.
remarque : GUI = Graphical User Interface
 
Nous allons étudier les instructions de cette page:
Pour cet exemple, il faut 4 instructions :
1) "Create a frame" : crée un cadre avec 3 arguments : le titre, la largeur et la hauteur de la zone de dessin.
On ne maîtrise pas toutes les dimensions de ce cadre, c'est pourquoi il s'appelle simplegui :
on a un minimum de paramètres à fournir, les autres des valeurs par défaut.
frame = simplegui.create_frame("Home", 300, 200)
import simplegui

# Create a frame : fenêtre de dessin noire de dimensions (300, 200) pixels
cadre = simplegui.create_frame("Home", 300, 200)
# Start the frame animation
cadre.start()
L'intruction "simplegui.create_frame" définit le cadre à construire
Le cadre est mis dans la variable (ou objet) "cadre"
2) l'instruction cadre.start( ) affiche le cadre et démarre son animation.
A partir de ce moment, le programme surveille ce qui se passe : comme un click dans le cadre.
 
N'hésitez pas à expérimenter en changeant les valeurs des arguments.
Le cadre est divisé en trois zones :
la zone blanche est la zone de contrôle :
on peut y mettre des boutons pour démarrer, arrêter, ...
on peut également y mettre des boîtes de saisie pour entrer des valeurs numériques.
en bas de la zone de contrôle, la seconde zone contient 2 boîtes toujours pésentes : Key et Mouse
qui ne nous n'utilisons pas dans ce cours.
Pour information, Key affiche la touche du clavier actionnée et Mouse affiche la position de la souris dans la fenêtre graphique.
la zone noire est la zone graphique dans laquelle on peut dessiner. Elle s'appelle "Canvas" en anglais c'est-à-dire "Toile" (à peindre).
3) "assign callbacks to event handlers" : associer des fonctions aux "gestionnaires d'évènements"
On ajoute un bouton "Cliquer !" dans la zone de contrôle (blanche) du cadre :
instruction add_button() appliquée à l'objet "frame" d'où l'écriture : frame.add_button(texte, fonction)
import simplegui

# Create a frame
frame = simplegui.create_frame("Home", 300, 200)

def cliquer():
    print("Je clique.")
    
frame.add_button("Cliquer !", cliquer)

# Start the frame animation
frame.start()

Le fait de cliquer sur un bouton avec la souris est un évènement.
Il déclenche l'appel à une fonction. Ici on crée un bouton portant le texte "Cliquer !"
et quand le bouton est cliqué, c'est la fonction cliquer() qui est appelée.
Cette fonction écrit "Je clique." pour montrer qu'elle est bien appelée.
 
4) frame.set_draw_handler(draw)
import simplegui

# Handler to draw on canvas
# draw_text( texte, position, taille, couleur )
# la position [0, 0] est en haut à gauche de la fenêtre
# la position [x, 0] est à x pixels vers la droite
# la position [0, y] est à y pixels vers le bas
def draw(canvas):
    texte = "Welcome!"
    position = [50,112]
    taille = 48
    couleur = "Red"
    canvas.draw_text(texte, position, taille, couleur)

# Create a frame and assign callbacks to event handlers
frame = simplegui.create_frame("Home", 300, 200)
frame.set_draw_handler(draw)

# Start the frame animation
frame.start()

La fonction "set_draw_handler( )" appliquée à un objet de type "Frame" associe une fonction "draw" qui va dessiner en permanence dans la partie "canvas" à partir de start( ).
Si l'on dessine toujours la même image, on ne s'en aperçoit pas.
  Mais on peut décaler l'image d'un pixel à chaque appel pour voir que cette fonction est appelée sans interruption:
on sort : position = [50,112] de la fonction "draw"
et on la remplace par l'instruction :
position[0] = ( position[0] + 1 ) % 300
qui ajoute 1 dans la direction x et calcule le reste de la division par 300 pour ramener l'image dans le cadre quand sa position dépasse 300
import simplegui

# Handler to draw on canvas
# draw_text( texte, position, taille, couleur )
# la position [0, 0] est en haut à gauche de la fenêtre
# la position [x, 0] est à x pixels vers la droite
# la position [0, y] est à y pixels vers le bas
position = [50,112]
def draw(canvas):
    global position
    texte = "Welcome!"
    position[0] = (position[0] + 1) % 300
    taille = 48
    couleur = "Red"
    canvas.draw_text(texte, position, taille, couleur)

# Create a frame and assign callbacks to event handlers
frame = simplegui.create_frame("Home", 300, 200)
frame.set_draw_handler(draw)

# Start the frame animation
frame.start()

Comment faire pour que la fin du texte qui disparaît sur la droite réapparaisse tout de suite à gauche?
astuce : Dessiner un deuxième texte décalé de 300 vers la gauche :
position1 = [ position[0]-300, position[1] ]
canvas.draw_text(texte, position1, taille, couleur)
fin provisoire du cours.

précédent : solutions du chapitre 2 (Python en mode texte)
menu : cours simulation