cours 11

publicité
Algorithmique et Programmation Python
Printemps 2013
Bruno Martin & Jean-Paul Roy
L1 Sciences Fondamentales - Faculté des Sciences
Cours n°11
Programmation classique (séquentielle)
http://deptinfo.unice.fr/~bmartin/python.html
Initialisation
Programmation
d'une interface
graphique
Traitement
Terminaison
Initialisation :
• importe des modules; ouvre des fichiers; accède au réseau
Traitement :
• gère l'affichage, calcule, modifie les données
Terminaison :
• quitte proprement l’application
Introduction
• tkinter : bibliothèque provenant de l’extension graphique Tk du
langage Tcl (1988).
• L’extension a largement dépassé le cadre de Tcl/Tk.
Programmation événementielle
Initialisation
Traitement
(non séquentielle)
Terminaison
• Tk utilisable dans différents langages (Perl, Python, Ruby, ...)
• En python, c’est tkinter :
Tk interface
• Permet de réaliser un GUI (Graphical User Interface)
• GUI : une interface homme-machine permettant à l’utilisateur
d’interagir avec la machine autrement que par le shell.
Initialisation:
• crée les composants graphiques;
• fait le lien composant-événement-action
Traitement :
• créée les fonctions relatives aux actions
• se met en attente d’un événement (interaction avec utilisateur)
• exécute l’action liée
Terminaison :
• quitte proprement l’application
Gestionnaire d’événements
Structure du programme
Initialisations
événements
gestionnaire
messages
Fonctionnalités
du
programme
Terminaison
• écoute les événements des périphériques (clavier, souris, etc)
• réagit à l’apparition d’un événement
• envoie un message au programme
• exécute un bloc de code (fonction ou méthode) spécifique
• PROGRAMMATION DIRIGEE PAR LES EVENEMENTS !
from tkinter import *
initialisation
root=Tk()
création de la fenêtre maître
message = Label(root,\
text = 'Un premier exemple !'\
fg = 'red')
boutonQuit = Button(root,\
text = 'Quit',\
command = root.destroy)
message.pack()
boutonQuit.pack()
affichage des composants
root.mainloop()
lancer le gestionnaire d’événements
exit(0)
quitter proprement
Les widgets : gadgets de fenêtrage
Création de widgets
• widget = window gadget : tous les composants de l’écran (fenêtres,
boutons, ascenseurs, ...)
• Chaque widget est un objet python.
• Tk assure la gestion des widgets :
- fenêtre de composants (Frame)
- fenêtre de dessin (Canvas)
- affichage d'informations (Label, Message, Text)
- interaction avec les composants (Button, Scale, ...)
- saisie de texte (Entry)
• Création de widget : passer le parent de la hiérarchie en argument de
la fonction de création (sauf pour root).
• Les widgets ont beaucoup d’options de configuration (couleur, position,
etc...).
from tkinter import *
root=Tk()
etiquette=Label(root,text='Exemple')
etiquette.pack()
• Tous les widgets sont des éléments d’une hiérarchie :
root
parent
contenu du Frame
texte
(Label)
bouton
(Button)
définition des composants
option de configuration
etiquette=Label(root,text='Un premier exemple !',fg='red')
boutonQuit=Button(root,text='Quit',command=root.destroy)
création bouton
interaction avec
composant
Les couleurs
Un petit logiciel d'automate cellulaire 1-D
• Une couleur peut s’exprimer :
• Il sera constitué de trois acteurs bien distincts :
- soit par une chaîne de caractères constante : message['fg']='red'
'red' 'blue' 'black' 'green' 'white' 'yellow' 'gray', etc
- soit par un mélange RGB à la place du texte, en hexadécimal
message['fg']='#ff0000'
Ex : la couleur jaune s’obtient avec un mélange de rouge et de vert:
jaune = '#ffff00' ; message['fg'] = jaune
- Une partie (le MODELE) sera chargée de décrire le modèle
mathématique de calcul, ici par l'intermédiaire d'une classe Python.
- Une autre partie (la VUE) sera chargée de visualiser l'état
courant du modèle mathématique dans une fenêtre graphique.
- Quant à Tkinter (le
CONTROLEUR), il jouera le
rôle de chef d'orchestre en
se mettant à l'écoute de
l'utilisateur. Il assurera la
synchronisation entre le
Modèle et la Vue.
http://gnuprog.info/prog/python/pwidget.php
NB : Le schéma MVC prend soin de bien séparer les trois parties...
Un automate cellulaire 1-D
Modèle : une classe CA d’automates cellulaires
• Un automate cellulaire à 1 dimension est constitué de cellules
disposées sur une ligne. Une cellule peut être morte(0) ou vivante(1).
• L'automate va évoluer. A chaque génération, toutes les cellules sont
transformées. L'état suivant d'une cellule est fonction de son état
actuel et de ceux de ses voisines immédiates. Suivant une REGLE.
• Exemple, la règle n° 30 :
111 110 101 100 011 010 001 000
• Pourquoi n° 30 ? A cause du binaire :
n
n+1
256
règles !
>>> 0b00011110
30
on recolle
les bords !
• L'état d'un objet de la classe CA (Cellular Automaton) consiste en la
donnée de deux attributs : une configuration et une règle (des listes).
>>> ca = CA('0010110',30)
>>> bin(30)
'0b11110'
>>>
[0,
>>>
[0,
ca.config
0, 0, 1, 0, 1, 1, 0, 0]
ca.regle
0, 0, 1, 1, 1, 1, 0]
class CA :
def __init__(self,cfg='1011',n=30) :
self.config = [int(cfg[-1])] + [int(i) for i in cfg] + [int(cfg[0])]
s = [int(i) for i in bin(n)[2:]]
self.regle = (8-len(s)) * [0] + s
def __str__(self) :
return str(self.config[1:-1])
.....
>>> print(ca)
[0,0,1,0,1,1,0]
L'évolution de l'automate
• La méthode next() va faire évoluer la configuration de l'automate,
suivant sa règle :
>>> print(ca)
[0,0,1,0,1,1,0]
>>> ca.next()
>>> print(ca)
[0,1,1,0,1,0,1]
# génération suivante !
111 110 101 100 011 010 001 000
def next(self) :
L = len(self.config) * [0]
# le résultat à remplir
for i in range(1,len(L)-1) :
v = self.config[i-1:i+2]
# v == [1,1,0]
k = int(str(v[0])+str(v[1])+str(v[2]),2)
# k == 6
# on récupère donc l'élément numéro 7-k de la règle
L[i] = self.regle[7-k]
(L[0],L[-1]) = (L[-2],L[1])
# recollement des bords
self.config = L
Création du canvas 400 x 300
from tkinter import *
root=Tk()
root.title('automate cellulaire unidimensionnel')
canvas=Canvas(root,width=400,height=300,bg='gray')
root.mainloop()
(0,0)
fenêtre principale (root)
titre de la fenêtre principale
initialisation
définition d'un
composant
affichage du composant
canvas.pack(side=left)
(0,300)
L'interface graphique avec tkinter
création de la fenêtre maître
(400,0)
lancement du gestionnaire
d’événements
• Mise à part la tortue, il est usuel
en programmation de prendre
l'origine des coordonnées en haut
à gauche, l'axe 0y vers le bas !
Dessiner et écrire dans le canvas
from tkinter import *
root = Tk()
Bouton pour
quitter
Bouton pour
exécuter
zone d'affichage
(canvas)
champ de saisie
du numéro de la
règle
Texte fixe
champ de
saisie de la
configuration
initiale
Texte fixe
root.title('Automate cellulaire unidimensionnel')
canvas=Canvas(root,width=400,height=300,bg='gray')
canvas.pack(side=left)
canvas.create_oval( 40,20,120,200 ,outline="red",fill="green", width=2)
canvas.create_rectangle(230,50,320,100,fill='yellow',width=10)
canvas.create_line(40,20,120,200)
canvas.create_text(200,150,\
text="Je sais écrire !!!",\
font=('copperplate',36))
root.mainloop()
Saisir une entrée et récupérer le contenu
• Le composant dans lequel l'utilisateur peut entrer la configuration est
dans la classe Entry de tkinter. Idem pour le composant dans lequel il
entrera le numéro de règle. Plaçons ces deux composants dans le canvas.
config = Entry(canvas)
config.pack()
canvas.create_window(175,280,\
width=250,window=config)
canvas.create_text(25,280,text='config')
rule = Entry(canvas)
rule.pack()
canvas.create_window(370,280,\
width=35,window=rule)
canvas.create_text(330,280,text='rule')
250
(175,280)
• On pourra récupérer le contenu de l'Entry rule par : rule.get() qui
retournera une chaîne de caractères !
Les deux boutons et leur callback
• Un bouton est un composant de la classe Button de tkinter. Son
attribut le plus important est command, contenant une fonction d'arité 0.
Cette fonction (le callback du bouton) sera automatiquement exécutée
suite à un clic de l'utilisateur dans le bouton.
boutonQuit = Button(root,text='Quit',command=root.quit)
boutonRun = Button(root,text='Run',command=executer)
boutonQuit.pack()
boutonRun.pack()
• La fonction root.quit() est définie
par tkinter, elle termine le logiciel !
• Il vous reste à définir en TP la
fonction executer() qui va construire
un automate cellulaire et en dessiner
30 générations dans le canvas...
Résumé de l'interface graphique
root=Tk()
root.title('Automate cellulaire unidimensionnel')
fenêtre principale (root)
titre fenêtre principale
Bouton quitter
affichage (canvas)
canvas=Canvas(width=400,height=300,bg='gray')
canvas.pack(side=LEFT)
Bouton Run
champ saisie rule
Texte config
rule=Entry(canvas,width=20)
rule.pack()
canvas.create_window(370,280,\
width=35,window=rule)
canvas.create_text(25,280,text="config")
Texte rule
champ saisie config
canvas.create_text(330,280,text="rule")
config=Entry(canvas)
config.pack()
canvas.create_window(175,280,width=250,window=config)
Téléchargement