Vous êtes sur la page 1sur 32

PROGRAMMATION ORIENTÉE OBJET (POO)

« Apparue dans les années 1960, la programmation orientée objet (POO) est un
paradigme de programmation ; c’est-à-dire une façon de concevoir un programme
informatique, reposant sur l’idée qu’un programme est composé d’objets interagissant
les uns avec les autres.

En définitive, un objet est une donnée. Une donnée constituée de diverses propriétés,
et pouvant être manipulée par différentes opérations. » 1

A. TERMINOLOGIE ET SYNTAXE :
Classes, instances de classe et méthodes de classe

Un exemple simple :

Médor est un chien. Pendant une journée typique, il fait diverses actions : il mange, il court, il dort, etc.

I. LA SYNTAXE
En POO on pourra écrire cela :

• Médor = Chien()

• Médor.mange()

• Médor.court()

• Médor.dort()

De plus, Médor a diverses qualités ou attributs ou propriétés (taille, couleur de poil,etc). On peut
exprimer ceci comme suit :

• Médor.taille = "grand"

• Médor. couleurDePoil = "noir&blanc"

II. TERMINOLOGIE
En POO on utilise les termes suivants : classe, instance de classe (ou objet), attributs et méthodes de classe.

• Chien est une classe d'objets

• Médor est une instance de classe (ou objet) de la classe « Chien »

• mange(), court() et dort() sont des méthodes de la classe Chien ; les méthodes sont des fonctions
qui appartiennent à une classe.

• taille et couleurDePoil sont des attributs (ou propriétés) d’une instance donnée

La relation entre un attribut ou une méthode et l’objet est indiquée par un point écrit entre les deux.

1 :https://zestedesavoir.com/tutoriels/pdf/1253/la-programmation-orientee-objet-en-python.pdf
Classe : description des caractéristiques d'un objet. Elle décrit les variables que comportent tous les objets
de la même classe.

Instance : tout objet créé à partir de cette classe. La classe est une sorte de "moule" pour les instances
d'objets.

Méthodes : ce sont des fonctions internes à une classe agissant sur les instances de la classe.

B. PROGRAMMES ORIENTÉS OBJET


I. PREMIER PROGRAMME EN POO
A) LE CODE
# nom programme : p_classe_personne

# création classe Personne avec deux attributs


class Personne:
def __init__(self,n,a):
self.nom = n
self.age = a

# création d'une instance dans la classe Personne


p1 = Personne("Albert",27)
print("nom et âge de p1 : ", p1.nom , " " , p1.age)
# création d'un nouvel objet de type Personne
p2 = Personne("Evelyne",47)
print("nom et âge de p2 : " ,p2.nom, " " , p2.age)
# modifier les attributs de objet p1
p1.age = 28
p1.nom =" Einstein"
print("nom et âge modifiés de p1 : " , p1.nom, " " ,p1.age)

B) QUE FAIT CE PROGRAMME ?


Il crée une classe nommée Personne puis :

• Il définit pour cette classe deux attributs : nom et age

• Il crée une instance de la classe Personne nommée p1

• Il crée un deuxième objet de cette classe nommée p2

• Il modifie les attributs de l'objet p1

II. SYNTAXE PYTHON ET POO


A) DÉFINIR UNE CLASSE
class Nomclasse :

Par convention le nom d’une classe commence toujours par une majuscule, mais ce n'est pas une
obligation. Ne pas oublier les « : » pour marquer le début de bloc

Dans le même bloc il faut définir les attributs et méthodes de la classe.


B) DÉFINIR LES ATTRIBUTS DE CLASSE
def __init__(self,param1, param2, ...):
self.variable1=param1
self.variable2=param2
...
Le mot "self" est obligatoire.

La fonction –init--() est une fonction spéciale qui porte le nom de constructeur qui sert à initialiser les
attributs d’une classe. Ce constructeur existe toujours en programmation orientée objet. Cette méthode
spéciale exécutée lors de l'instanciation de la classe permet de créer l'objet en créant les variables que
contient l'objet, en définissant leur valeur initiale ou en effectuant certaines opérations. De manière
analogue, il existe le destructeur appelé lors de la destruction de l'objet.

C) DÉFINIR UNE MÉTHODE DE CLASSE


def méthode(self):
return expression
Il faut au minimum le paramètre "self" (mais il peut y en avoir d’autres). Le mot "self" sera expliqué ci-
dessous. expression est construite à partir des attributs.

D) CRÉER UNE INSTANCE DE CLASSE


nomObjet = NomClasse(arguments)

E) MODIFIER LES ATTRIBUTS D'UN OBJET


nomObjet.attribut = nouvelle valeur

F) APPLIQUER UNE MÉTHODE À UN OBJET


nomObjet.méthode()

III. LE MOT SELF


Une des particularités des méthodes est que l’objet appelant est passé comme premier argument de la
fonction telle que définie dans la classe. Ainsi, lorsqu’on écrit Médor.mange() par exemple, l’objet Médor est
passé de manière implicite à mange(). Aussi une méthode possède toujours à minima le paramètre self et
lorsqu'on appelle la méthode, il n'y a aucun argument à saisir.

Par exemple, si la fonction --init--() comprend trois paramètres (dont self), il faut alors passer deux
arguments pour créer une nouvelle instance de classe.

IV. CLASSES ET PRINCIPE D’ENCAPSULATION


Le principe d'encapsulation est un des concepts clés de la programmation objet. Les classes permettent de
mettre en place ce qu'on appelle l'encapsulation du code c'est-à-dire le compartimentage des variables et
des fonctions. En effet chaque objet créé à partir d’une classe possède ses attributs et méthodes qui ne sont
pas accessibles à l'extérieur de l'objet. Cette technique permet de regrouper des données au sein d'une
classe et de pouvoir les lire et les manipuler par le biais de méthodes qui forment une interface pour les
éléments environnant l'objet. De ce fait, les variables et les méthodes contenues au sein d'une classe
peuvent être placées dans trois niveaux de visibilité en fonction de la portée souhaitée :

Public
La variable ou fonction est accessible à tous.
Protégé
Les attributs sont accessibles uniquement à la classe et les classes filles.
Privé
Les attributs ne sont visibles que par la classe elle-même. Pour rendre un attribut ou une
méthode privé en python, il faut faire précéder le nom de l’attribut d’un caractère « _ ». Mais
attention ceci n’est qu’une convention...Python ne gère pas les attributs ou méthodes
privées !
Pour respecter le principe fondamental de l'encapsulation, toutes les variables doivent être privées et ne
sont accessibles qu'à travers des méthodes conçues pour les modifier qu'après les avoir vérifiées ou les
retourner formatées.

C. HÉRITAGE
En POO, on dit qu’un objet « hérite » des méthodes de sa classe ; cela signifie qu'une instance de classe a
accès aux méthodes de cette classe.

Ainsi une instance de la classe Chien a accès aux méthodes mange(), court() et dort(). Une classe peut
« hériter » d'une autre classe : une classe dite "fille" hérite de toutes les variables et fonctions de la classe
parent ou classe mère (et notamment de sa fonction __init_()). L'intérêt de cette opération est de partager
des variables et des méthodes communes à différentes classes. La classe fille peut alors ajouter des
éléments pour compléter l'héritage de la classe mère ou peut écraser certaines méthodes ou variables avec
son contenu propre.

On parle d'héritage simple dans le cas où une classe fille a recours à une seule classe mère. Par extension,
on parle d'héritage multiple si une classe fille hérite des attributs de plusieurs classes mères.

L'héritage a plusieurs propriétés :

Transitivité
Si une classe B hérite de la classe A, et que C hérite de B, alors C hérite de A.
Non réflexif
Une classe ne peut hériter d'elle-même.
Non symétrique
La classe fille hérite de la classe mère mais la classe mère n'hérite pas de la classe fille.
Sans cycle
Il n'est pas possible que la classe B hérite de la classe A, que la classe C hérite de la classe B
et que la classe A hérite de la classe C.
I. EXEMPLE DE PROGRAMME AVEC HÉRITAGE
A) LE CODE
# nom programme : heritage.py

#création d'une classe Personne avec deux attributs


class Personne:
def __init__(self,nom,age):
self.nom = nom
self.age=age

# La classe Etudiant hérite de la classe mère Personne


class Etudiant(Personne):
# définition des attributs
def __init__(self, nom, age, filiere):
# héritage des attributs depuis la classe mère Personne
Personne.__init__(self, nom, age)
# ajout d'un nouvel attribut filiere à la classe Etudiant
self.filiere = filiere

etudiant1 = Etudiant("Albert",27,"math")
print("nom, âge, filière : " ,etudiant1.nom, " ", etudiant1.age, "
" ,etudiant1.filiere)
#créer d'une nouvelle instance de la classe Etudiant
etudiant2 =Etudiant("Isabelle",21,"informatique")
print("nom, âge, filière : " ,etudiant2.nom, " ", etudiant2.age, "
" ,etudiant2.filiere)

B) QUE FAIT CE PROGRAMME ?


Il crée une classe « Personne » avec deux attributs : nom et age

Il crée la classe « Etudiant » à partir de « Personne » : Cette classe récupère les attributs de la classe mère et
on ajoute un troisième attribut « filiere ».

Création d'une première instance de Etudiant : etudiant1

Création d'un deuxième objet Etudiant : etudiant2

II. REMARQUE SYNTAXIQUE


Les paramètres de la fonction –init--() peuvent être identiques aux noms des variables (attributs) définis par
cette fonction.

Exemple :
def __init__(self,nom,age):
self.nom = nom
self.age=age
class Etudiant(Personne): cette instruction signifie que la classe « Etudiant » hérite de la classe
« Personne ».

Personne.__init__(self, nom, age) : instruction pour récupérer les attributs nom et age de Personne

self.filiere = filiere : instruction pour créer un troisième attribut.

III. DEUXIÈME PROGRAMME


A) LE CODE
# nom programme : heritage.py

#création d'une classe Personne


class Personne:
def __init__(self,nom,age):
self.nom = nom
self.age=age

# La classe fille Etudiant hérite de la classe mère Personne


class Etudiant(Personne):
# définition des attributs
def __init__(self, nom, age, filiere):
# héritage des attributs depuis la classe mère Personne
Personne.__init__(self,nom,age)
# ajout d'un troisième attribut
self.filiere = filiere
#ajout d'une méthode
def affiche(self):
return self.nom + " " + str(self.age) + " "+ self.filiere

#créer une instance de Etudiant


etudiant1 = Etudiant("Albert",27,"math")
print("Nom, âge, filière : " ,etudiant1.nom, " ", etudiant1.age, "
" ,etudiant1.filiere)

#modifier les attributs d'un objet


etudiant1.nom ="Alberta"
etudiant1.age = 28

#utiliser la méthode affiche() à l'objet etudiant1


print("nom, âge, filière : " ,etudiant1.affiche())

#créer d'une nouvelle instance de Etudiant


etudiant2 =Etudiant("Isabelle",21,"informatique")

#utiliser la méthode affiche() à l'objet etudiant2


print("Nom, âge,filiere :", etudiant2.affiche())

B) QUE FAIT CE CODE DE PLUS PAR RAPPORT AU PRÉCÉDENT ?


Il définit dans la classe Etudiant une méthode affiche() qui produit la fiche de l'étudiant.

Il est en effet beaucoup plus simple d'écrire print(nomObjet.affiche()) que print(nomObjet.nom , " ",
nomObjet.age , " ", nomObjet.filiere). Et encore, ici il n'y a que trois variables. Mais s'il y en avait 10 !

D. MODÉLISATION POUR LA PROGRAMMATION ORIENTÉE OBJET


Dans ce chapitre est abordé la modélisation des objets afin de les mettre en œuvre en Python. La
modélisation est basée sur une représentation en langage UML (Unified Modeling Langage), largement
utilisé en génie logiciel.

I. L’OBJET
En UML, on représente le type de données retournées par une méthode en terminant le nom de la
méthode avec deux points suivis du type de données. Si la méthode ne retourne rien, on inscrit void.

La représentation UML représente une classe par un rectangle divisé horizontalement en trois parties dont
le premier tiers renseigne le nom de la classe, le second décrit les attributs de celle-ci et le troisième tiers
liste les méthodes de la classe.

Pour illustrer le concept d'objet, reprenons pour exemple la modélisation d'une personne. Cette personne a
un nom, un prénom, une date de naissance et un lieu de résidence. La classe comporte également la
méthode demenager qui permet de changer de lieu de résidence, ainsi que la méthode calculerAge
retournant l'âge sous forme d'un entier. Nous allons modéliser cela sous la forme d'une classe :

Figure 1: Représentation UML de la classe Personne


II. L'HÉRITAGE
Pour modéliser le mécanisme d’héritage, on peut prendre l’exemple de la classe Chien et d’une classe
Poule qui héritent toutes deux de la classe Animaux. La flèche terminée par un triangle indique
l'héritage.

Un autre exemple, celui d'une imprimante multifonction permet d’illustrer l'héritage multiple. Elle permet à
la fois de scanner et d'imprimer : La photocopie est une combinaison des deux opérations précédentes.

E. L'ENCAPSULATION
Cela se représente dans un diagramme UML par un caractère précédant le nom de l'attribut ou de la
méthode tel que décrit dans le tableau suivant.

Caractère Rôle
+ Accès public
# Accès protégé
- Accès privé
Illustration :
F. L'ASSOCIATION
Enfin, il est naturellement possible d'utiliser certains objets dans les variables d'autres objets. On modélise
l'association entre les classes par un trait et on fait figurer le type de l'objet en vis-à-vis du nom de la
variable, séparés par deux points. On peut faire figurer une association monodirectionnelle avec une flèche.

G. L'AGRÉGATION ET LA COMPOSITION
L'agrégation et la composition désignent le fait qu'un objet soit composé d'autres objets. La composition
entraîne l'appartenance du sous-objet à l'objet alors que l'agrégation non. Par exemple le cas d'une
université composée de départements qui agrègent des professeurs. Lors de la destruction de l'université,
les départements sont détruits, mais pas les professeurs. L'agrégation est représentée par un lien terminé
par un losange vide (♢) et la composition est un lien terminé par un losange plein (♦). Nous allons
représenter l’université par un diagramme UML.
MANIPULER LES FICHIERS2
Il peut être nécessaire de lire ou d'écrire des fichiers stockés sur l'ordinateur exécutant vos scripts.
Consigner des données dans des fichiers permet de simplifier un programme en externalisant les données
et peut être un moyen de s'interfacer avec d'autres programmes et systèmes ainsi qu'avec les utilisateurs.
Nous utiliserons la fonction open() fournie par défaut. Avant tout, il est nécessaire de voir comment
naviguer dans l'arborescence.

A. NAVIGATION DANS L'ARBORESCENCE


En fonction du répertoire dans lequel est exécuté votre script, il peut être nécessaire de changer de
répertoire de travail du script. Pour se faire, nous utiliserons la fonction chdir(repertoire) dans le
module os pour changer de répertoire de travail. Nous utiliserons également la fonction getcwd() du
même module. Il est possible de créer un dossier avec mkdir(chemin) :

from os import getcwd, chdir, mkdir

chemin = getcwd()
print(chemin)

mkdir('test')

print(getcwd())

chdir('test')

print(getcwd())

B. OUVRIR UN FICHIER
Pour lire un fichier, il faut tout d'abord ouvrir un flux de lecture ou d'écriture de fichier avec la fonction
open(fichier,mode (par défaut : 'rt')) avec fichier l'adresse du fichier à ouvrir et mode, le type de
flux à ouvrir. Le mode est composé de deux lettres, les droits d'accès (rwxa) et l'encodage (bt).

Caractère Action
'r' Ouvrir en lecture seule (défaut)
'w' Ouvrir en écriture. Écrase le fichier existant.
'x' Ouvrir en écriture si et seulement si le fichier n'existe pas déjà.
'a' Ouvrir en écriture. Ajoute au fichier existant.
'b' Mode binaire.
't' Mode texte (défaut).
Pour fermer le flux de fichier avec la méthode close() sur la variable représentant le flux.

Il est important de fermer le flux une fois les opérations sur le fichier terminées.

2 https://python.antoinepernot.fr/cours.php?course=chap5
C. LIRE UN FICHIER
Une fois le flux ouvert en lecture, on peut utiliser les méthodes read() qui retournent une chaîne de
caractères contenant l'intégralité du fichier ou readlines() retournant une liste où chaque élément est
une ligne du fichier.
fichier = open("texte.txt",'rt')
texte = fichier.read()
print(texte)

lignes = fichier.readlines()
print(lignes)

fichier.close()
Chaque ligne est terminée par "\n" qui représente un retour à la ligne. Il s'agit d'un caractère spécial. Si
vous écrivez ce caractère dans une chaîne de caractères, Python produira un retour à la ligne.

D. ÉCRIRE UN FICHIER
On peut écrire un fichier si le flux est ouvert en écriture. Les trois flux possibles sont "w", "x" et "a". À
l'instar de read() et readlines(), on utilisera write(chaine) pour écrire une chaîne de caractères
et writelines(lignes) avec lignes une liste ou un tuple dont chaque élément est une ligne à
écrire. N'oubliez pas le caractère \n en fin de ligne pour revenir à la ligne.

fichier = open("texte.txt",'wt')
fichier.write("Lorem ipsum dolor sit amet, consectetur adipiscing elit. \nPellentesque
gravida erat ut lectus convallis auctor. \nFusce mollis sem id tellus auctor
hendrerit.")
fichier.close()

fichier = open("texte.txt",'wt')
fichier.writelines(["Lorem ipsum dolor sit amet, consectetur adipiscing elit. \n",
"Pellentesque gravida erat ut lectus convallis auctor. \n", "Fusce mollis sem id tellus
auctor hendrerit."])
fichier.close()

E. FORMATS DE FICHIERS
Il existe différents formats standards de stockage de données. Il est recommandé de favoriser ces formats
car il existe déjà des modules Python permettant de simplifier leur utilisation. De plus, ces formats sont
adoptés par d'autres programmes avec lesquels vous serez peut-être amené à travailler.

F. FORMAT CSV
Le fichier Comma-separated values (CSV) est un format permettant de stocker des tableaux dans un fichier
texte. Chaque ligne est représentée par une ligne de texte et chaque colonne est séparée par un séparateur
(virgule, point-virgule …).

Les champs texte peuvent également être délimités par des guillemets. Lorsqu'un champ contient lui-même
des guillemets, ils sont doublés afin de ne pas être considérés comme début ou fin du champ. Si un champ
contient un signe pouvant être utilisé comme séparateur de colonne (virgule, point-virgule …) ou comme
séparateur de ligne, les guillemets sont donc obligatoires afin que ce signe ne soit pas confondu avec un
séparateur.
Voici des données présentées sous la forme d'un tableau et d'un fichier CSV :
Nom;Prénom;Age
"Dubois";"Marie";29
"Duval";"Julien ""Paul""";47
Jacquet;Bernard;51
Martin;"Lucie;Clara";14
Données sous la forme d'un fichier CSV

Nom Prénom Age


Dubois Marie 29
Duval Julien "Paul" 47
Jacquet Bernard 51
Martin Lucie;Clara 14
Données sous la forme d'un tableau

Le module csv de Python permet de simplifier l'utilisation des fichiers CSV.

I. LIRE UN FICHIER CSV


Pour lire un fichier CSV, vous devez ouvrir un flux de lecture de fichier et ouvrir à partir de ce flux un lecteur
CSV.

Remarque : Pour ignorer la ligne d'en-tête, utilisez next(lecteurCSV).

import csv
fichier = open("noms.csv", "rt")
lecteurCSV = csv.reader(fichier,delimiter=";") # Ouverture du lecteur CSV en lui
fournissant le caractère séparateur (ici ";")
for ligne in lecteurCSV:
print(ligne) # Exemple avec la 1e ligne du fichier d'exemple : ['Nom', 'Prénom',
'Age']
fichier.close()
Vous obtiendrez en résultat une liste contenant chaque colonne de la ligne en cours. Vous pouvez modifier
le délimiteur de champs texte en définissant la variable quotechar.

import csv
fichier = open("noms.csv", "rt")
lecteurCSV = csv.reader(fichier,delimiter=";",quotechar="'")
# Définit l'apostrophe comme délimiteur de champs texte
for ligne in lecteurCSV:
print(ligne)
fichier.close()
Vous pouvez également lire les données et obtenir un dictionnaire par ligne contenant les données en
utilisant DictReader au lieu de reader.

import csv
fichier = open("noms.csv", "rt")
lecteurCSV = csv.DictReader(fichier,delimiter=";")
for ligne in lecteurCSV:
print(ligne) # Résultat obtenu : {'Age': '29', 'Nom': 'Dubois', 'Prénom': 'Marie'}
fichier.close()

II. ÉCRIRE UN FICHIER CSV


Comme pour la lecture, il faut ouvrir un flux d'écriture et ouvrir un « écrivain CSV » à partir de ce flux.
import csv
fichier = open("annuaire.csv", "wt")
ecrivainCSV = csv.writer(fichier,delimiter=";")
ecrivainCSV.writerow(["Nom","Prénom","Téléphone"]) # On écrit la ligne d'en-tête
avec le titre des colonnes
ecrivainCSV.writerow(["Dubois","Marie","0198546372"])
ecrivainCSV.writerow(["Duval","Julien \"Paul\"","0399741052"])
ecrivainCSV.writerow(["Jacquet","Bernard","0200749685"])
ecrivainCSV.writerow(["Martin","Julie;Clara","0399731590"])
fichier.close()
Nous obtenons le fichier suivant :
Nom;Prénom;Téléphone
Dubois;Marie;0198546372
Duval;"Julien ""Paul""";0399741052
Jacquet;Bernard;0200749685
Martin;"Julie;Clara";0399731590
Il est également possible d'écrire le fichier en fournissant un dictionnaire par ligne à condition que chaque
dictionnaire possède les mêmes clés. On doit également fournir la liste des clés des dictionnaires avec
l'argument fieldnames.

import csv
bonCommande = [
{"produit":"cahier", "reference":"F452CP", "quantite":41, "prixUnitaire":1.6},
{"produit":"stylo bleu", "reference":"D857BL", "quantite":18,
"prixUnitaire":0.95},
{"produit":"stylo noir", "reference":"D857NO", "quantite":18,
"prixUnitaire":0.95},
{"produit":"équerre", "reference":"GF955K", "quantite":4, "prixUnitaire":5.10},
{"produit":"compas", "reference":"RT42AX", "quantite":13, "prixUnitaire":5.25}
]
fichier = open("bon-commande.csv", "wt")
ecrivainCSV = csv.DictWriter(fichier,delimiter=";",fieldnames=bonCommande[0].keys())
ecrivainCSV.writeheader() # On écrit la ligne d'en-tête avec le titre des
colonnes
for ligne in bonCommande:
ecrivainCSV.writerow(ligne)
fichier.close()
Nous obtenons le fichier suivant :
reference;quantite;produit;prixUnitaire
F452CP;41;cahier;1.6
D857BL;18;stylo bleu;0.95
D857NO;18;stylo noir;0.95
GF955K;4;équerre;5.1
RT42AX;13;compas;5.25
Par défaut, Python placera les guillemets autour des chaînes contenant des guillemets, une virgule ou un
point virgule afin que ceux-ci ne soient pas confondus avec un délimiteur de champs ou le séparateur. Afin
que tous les champs soient encadrés par les guillemets, nous allons modifier l'argument quoting pour
writer ou DictWriter .

import csv
fichier = open("annuaire.csv", "wt")
ecrivainCSV = csv.writer(fichier,delimiter=";",quotechar="'", quoting=csv.QUOTE_ALL)
# quotechar modifie le caractère délimitant un champ (par défaut : ")
ecrivainCSV.writerow(["Nom","Prénom","Téléphone"]) # On écrit la ligne d'en-tête avec
le titre des colonnes
ecrivainCSV.writerow(["Dubois","Marie","0198546372"])
ecrivainCSV.writerow(["Duval","Julien \"Paul\"","0399741052"])
ecrivainCSV.writerow(["Jacquet","Bernard","0200749685"])
ecrivainCSV.writerow(["Martin","Julie;Clara","0399731590"])
fichier.close()
Nous obtenons le fichier suivant :
'Nom';'Prénom';'Téléphone'
'Dubois';'Marie';'0198546372'
'Duval';'Julien "Paul"';'0399741052'
'Jacquet';'Bernard';'0200749685'
'Martin';'Julie;Clara';'0399731590'

G. SAUVEGARDER DES VARIABLES


Le module pickle permet de sérialiser des variables quelles qu'elles soient vers un fichier ouvert en flux
binaire et de les restaurer. Cela équivaut à sauvegarder et restaurer l'état des variables.

La fonction dump(variable, fichier) permet d'exporter une variable vers un fichier et la fonction
load(fichier) retourne la variable lue depuis le fichier.

L'ordre de sauvegarde et de restauration des variables doit être identique.


import pickle

texte = "Écrit par Antoine de Saint-Exupéry"


quantiteFournitures = {"cahiers":134, "stylos":{"rouge":41,"bleu":74}, "gommes": 85}
fournitures = ["cahier", "crayon", "stylo", "trousse", "gomme"]
fichierSauvegarde = open("donnees","wb")
pickle.dump(texte, fichierSauvegarde)
pickle.dump(quantiteFournitures, fichierSauvegarde)
pickle.dump(fournitures, fichierSauvegarde)
fichierSauvegarde.close()

import pickle

fichierSauvegarde = open("donnees","rb")
texte = pickle.load(fichierSauvegarde)
quantiteFournitures = pickle.load(fichierSauvegarde)
fournitures = pickle.load(fichierSauvegarde)
fichierSauvegarde.close()
print(texte)
Écrit par Antoine de Saint-Exupéry
print(quantiteFournitures)

{'stylos': {'bleu': 74, 'rouge': 41}, 'gommes': 85, 'cahiers': 134}

print(fournitures)

['cahier', 'crayon', 'stylo', 'trousse', 'gomme']

H. GÉRER LES FICHIERS


Python fournit deux modules permettant de gérer les fichiers et les répertoires. Le module os.path
permet de lister des fichiers et des répertoires. Le module shutil permet de copier, déplacer, supprimer
des éléments sur les systèmes de fichiers.

I. LES CHEMINS DE FICHIERS


Nous allons étudier les fonctions permettant de manipuler les chemins de fichiers ou de répertoires du
module os.path. La fonction basename(URI) renvoie le nom du fichier de l'adresse fourni en
argument. À l'inverse, la fonction dirname(URI) renvoie le chemin jusqu'au fichier, sans le nom du
fichier. Ces fonctions fonctionnent même si le fichier n'existe pas.
import os.path

chemin = "/tmp/dir/dir2/monFichier.txt"

print(os.path.basename(chemin))
monFichier.txt

print(os.path.dirname(chemin))
/tmp/dir/dir2

II. DIFFÉRENTIER LES FICHIERS ET LES RÉPERTOIRES


La fonction exists(URI) renvoie True si le fichier ou le répertoire fournis en argument existent. Les
fonctions isfile(URI) et isdir(URI) permettent respectivement de vérifier si le chemin mène à un
fichier et un répertoire. Ces fonctions renvoient True si c'est le cas.
import os.path

chemin = "/tmp/dir/dir2/monFichier.txt"
print(os.path.exists(chemin))

True

print(os.path.isfile(chemin))

True

print(os.path.isdir(chemin))

False

print(os.path.isdir(os.path.dirname(chemin)))

True

III. LISTER LE CONTENU D'UN RÉPERTOIRE


La fonction listdir(repertoire) du module os.path retourne le contenu du répertoire passé en
argument sans distinction entre les fichiers et les répertoires.
import os.path

print(os.listdir("/tmp/dir"))
['villes.json', 'quantiteFournitures.json', 'dir2']

IV. COPIER UN FICHIER OU UN RÉPERTOIRE


Il existe deux méthodes dans le module shutil permettant d'effectuer une copie. La fonction
copy(source, destination) permet de copier un fichier, alors que copytree en fait de même
avec les répertoires.
import shutil
shutil.copytree("/tmp/dir/dir2","/tmp/dir/dir3")
shutil.copy("/tmp/dir/dir2/monFichier.txt","/tmp/dir/exemple.txt")
V. DÉPLACER UN FICHIER OU UN RÉPERTOIRE
La fonction move(source, destination) du module shutil permet de déplacer un fichier ou un
répertoire. Cela peut également servir à renommer le fichier ou le répertoire.
import shutil
shutil.move("/tmp/dir/dir3","/tmp/dir/perso")

VI. SUPPRIMER UN FICHIER OU UN RÉPERTOIRE


La méthode remove(fichier) du module os et la fonction rmtree(dossier) du module shutil
permettent respectivement de supprimer un fichier et un répertoire.
import os,shutil
os.remove("/tmp/dir/exemple.txt")
shutil.rmtree("/tmp/dir/perso")

I. GESTION DES ERREURS


Lors de l'écriture de vos premiers scripts, vous avez peut-être rencontré ce type de message d'erreurs :
resultat = 42/0

Traceback (most recent call last):


File "<stdin>", line 1, in <module>
ZeroDivisionError: division by zero
Ce message signale l'erreur ainsi que la ligne à laquelle a été faite cette erreur. Or il est courant que les
erreurs ne soient pas des erreurs lors de la programmation mais une mauvaise manipulation de la part de
l'utilisateur. Par exemple, vous demandez à l'utilisateur de fournir un nombre et celui-ci vous fournit un
texte ou que le fichier, que vous cherchez à lire, n'existe pas.

Il faut alors gérer ce type d'erreurs afin d'éviter une interruption involontaire de l’application. Pour cela, il
faut utiliser les structures try.

Voici un exemple sur lequel est ajouté un mécanisme de gestion d'erreurs :


age = input("Quel est votre age : ")
age = int(age)
Voici l'erreur obtenue si la chaîne de caractères n'est pas un nombre :
age = input("Quel est votre age : ")
Quel est votre age : Alain
age = int(age)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: invalid literal for int() with base 10: 'Alain'
La structure try se présente ainsi :

try:
# La portion de code à tester
except:
# Que faire en cas d'erreur
Nous obtenons donc pour notre exemple :
age = input("Quel est votre age : ")
Quel est votre age : Alain
try:
... age = int(age)
... except:
... print("Erreur lors de la saisie. ")
...
Erreur lors de la saisie.
Il est possible d'identifier l'erreur et d'effectuer une action en conséquence. Nous pouvons donc chaîner les
instructions except en fournissant le type d'erreur. Le bloc else (optionnel) est exécuté s'il n'y a eu
aucune erreur.
try:
quantiteBoites = quantitePieces / nombresPiecesParBoites
except TypeError: # Type incompatible avec l'opération
print("Au moins une des variables n'est pas un nombre. ")
except NameError: # Variable non définie
print("Au moins une des variables n'est pas définie. ")
except ZeroDivisionError: # Division par 0
print("Le nombres de pièces par boites est égal à 0. ")
else:
print("Il faut commander " + str(quantiteBoites) + " boîtes. ")
Le bloc finally (optionnel) est exécuté dans tous les cas (s'il y a eu des erreurs ou non).

Enfin, l'instruction pass ne fait rien : elle permet de laisser un bloc vide ce qui est utile pour les exceptions.
LES INTERFACES GRAPHIQUES : MÉTHODE 13

A. LE MODULE TKINTER
Afin d’améliorer les entrées et sorties des fonctions input() & print() un peu austères, le module Tkinter
permet de réaliser d'agréables interfaces graphiques entre l'utilisateur et le programme. Tkinter est un
module intégré à la bibliothèque standard de Python. Donc il faut simplement l'importer. En fait avec ce
module il est possible de créer une fenêtre comprenant des éléments ou "widgets" : cadres, zones de texte,
cases à cocher, boutons radio, zone de listes, boutons de commande, etc. Ce module sera présenté via des
programmes de plus en plus complexes.

I. PREMIER PROGRAMME
Une fenêtre doit comprendre :

• Deux étiquettes

• Deux zones de texte (ou champs)

• Un bouton de commande

A) LE CODE
# nom programme : test_tkinter0.py
from tkinter import *

# Création d'un objet "fenêtre"


fenetre = Tk() # nouvelle instance de Tk
fenetre.title("Connexion ")
fenetre.geometry("300x150")

# pour saisir identifiant


label1 = Label(fenetre, text = "Votre identifiant ? ")
champ1 = Entry(fenetre, width=30)
label1.pack()
champ1.pack()

# pour saisir identifiant


label2 = Label(fenetre, text = "Votre mot de passe ? ")
champ2 = Entry(fenetre, width=30)
label2.pack()
champ2.pack()

# Bouton de commande
bouton1 = Button(fenetre, text = "connexion")
bouton1.pack()

fenetre.mainloop()

Il faut importer le module tkinter.

On crée une fenêtre, pour cela, on crée une instance de classe tk que l'on nomme "fenetre"

Puis on attribue à cette fenêtre un titre et une taille par défaut.

3 https://darchevillepatrick.info/python/python19.php#corps
Ensuite cinq widgets sont créés au sein de cette fenêtre :

• Une étiquette et une zone de texte pour saisir l'identifiant

• Une étiquette et une zone de texte pour saisir le mot de passe

• Un bouton de commande

Il faut toujours associer un "label" à un "entry" pour préciser à l'utilisateur ce qu'il doit saisir.

B) ANALYSE DES INSTRUCTIONS DU PROGRAMME


label1 = Label(fenetre, text = "Votre identifiant ? ") : définition d'une étiquette à l'intérieur de l'objet
parent. Il faut utiliser la méthode Label() avec deux arguments au moins : l'objet parent, le texte de
l'étiquette.

champ1 = Entry(fenetre, width=30) : définition d'une zone de texte à l'intérieur de l'objet parent. Il faut
utiliser la méthode Entry() avec deux arguments au moins : l'objet parent (ici "fenetre") puis la largeur du
champ (en pixels).

bouton1 = Button(fenetre, text = "connexion") : définition d'un bouton de commande à l'intérieur de l'objet
parent. Il faut utiliser la méthode Button() avec au moins deux arguments : l'objet parent, le texte du
bouton.

label1.pack() : positionner l'élément "label1" dans la fenêtre.

Il y a 5 widgets donc il y a donc cinq commandes de type pack.

fenetre.mainloop() : crée une boucle infinie dont on ne sortira que lorsque l'on fermera la fenêtre.

Attention à la "casse".

Les méthodes du module sont sensibles à la casse. Ainsi pour créer une étiquette il faut saisir Label (avec un
L majuscule) et pour définir une zone de texte il faut écrire Entry (avec un E majuscule).

C) REMARQUES
Le positionnement des éléments avec la méthode pack() est basique. Les widgets se placent les uns au-
dessous des autres et sont centrés horizontalement dans la fenêtre. Dans un deuxième programme sera
présenté le positionnement via une grille avec la méthode grid(). Attention on ne peut pas mélanger deux
techniques de positionnement dans une même fenêtre.

D) LE RENDU DE CE PROGRAMME
II. DEUXIÈME PROGRAMME
Ce programmes présente l’utilisation d'autres types de widgets et une autre façon de positionner
les widgets.

E) LE CODE
# nom programme : test_tkinter1.py
# objet : présentation de widgets moins connus
from tkinter import *

# Création d'un objet "fenêtre"


fenetre = Tk() # nouvelle instance de Tk
fenetre.title("Fiche de renseignements")
fenetre.geometry("450x400")
fenetre.minsize(300, 200)
fenetre.config(bg ="skyblue")
for i in range(1,6):
fenetre.rowconfigure(i, pad =15)

# spinbox
e1 = Label(fenetre, text = "Votre âge ? ")
spinbox1 = Spinbox(fenetre, from_=20, to=90, increment=1)
e1.grid(row =1, column =1)
spinbox1.grid(row =1, column =2)

#scale
e2 = Label(fenetre, text = "Votre poids ? ")
scale1 = Scale(fenetre, from_=40, to=100, showvalue=True, label='kilos' ,orient='h')
e2.grid(row =2, column =1)
scale1.grid(row =2, column =2)

#radiobutton ; rd
e3 = Label(fenetre, text = "Votre sexe ? ")
rb1 = Radiobutton(fenetre, text="femme" , value ="f")
rb2 = Radiobutton(fenetre, text="homme", value ="m")
e3.grid(row =3, column =1)
rb1.grid(row =3, column =2)
rb2.grid(row =3, column =3)

#checkbutton ; cc
e4 = Label(fenetre, text = "Jeux de cartes pratiqués ? ")
cc1 = Checkbutton(fenetre, text="belote")
cc2 = Checkbutton(fenetre, text ="tarot")
cc3 = Checkbutton(fenetre, text ="bridge")
e4.grid(row =4, column =1)
cc1.grid(row =4, column =2)
cc2.grid(row =4, column =3)
cc3.grid(row =4, column =4)

e5 = Label(fenetre, text = "sport premier pratiqué ? ")


items =Variable(fenetre, ("aucun", "tennis", "vélo", "foot", "natation", "autre"))
liste1 = Listbox(fenetre, listvariable=items)
e5.grid(row =5, column =1)
liste1.grid(row =5, column =2)

fenetre.mainloop()

F) COMMENTAIRE
Les nouveautés dans ce programme :
fenetre.geometry("450x400") : dimensions par défaut de la fenêtre.

fenetre.config(bg ="skyblue") : définition d'une couleur de fond pour la fenêtre.

for i in range(1,6):

____fenetre.rowconfigure(i, pad =15) : pour les 5 lignes de la grille on définit une marge externe de 15
pixels.

Ainsi les widgets ne seront pas collés car sinon la hauteur d'une ligne est égale à celle du widget le plus haut
dans la ligne.

Par défaut la largeur d'une colonne est égale à celle du widget le plus large dans la colonne. Il existe aussi la
méthode columnconfigure pour produire un espacement vertical.

spinbox1 = Spinbox(fenetre, from_=20, to=90, increment=1) : un "spinbox" permet de sélectionner une


valeur de l'intervalle défini en cliquant sur des flèches. Mais si l'intervalle est large, la saisie dans ce type de
widget devient fastidieuse.

e1.grid(row =1, column =1) : cette étiquette est placée dans la cellule L1C1 de la grille.

scale1 = Scale(fenetre, from_=40, to=100, showvalue=True, label='kilos' ,orient='h') : un widget de type


"scale" permet de sélectionner rapidement une valeur de l'intervalle défini. Ici la valeur sélectionnée est
affichée et le widget "scale" est dans l'exemple, orienté horizontalement.

rb1 = Radiobutton(fenetre, text="femme", value="f") : définition d'un bouton radio.

Il y a un deuxième bouton radio. Dans un groupe de boutons radio, un seul peut être coché.

cc1 = Checkbutton(fenetre, text="belote") : définition d'une case à cocher.

liste1 = Listbox(fenetre, listvariable=items) : définition d'une "listbox" (zone de liste). Cette liste est
construite à partir du tuple contenu dans la variable "items".

Dans cet exemple, la méthode grid() est utilisée pour le positionnement sur une grille, d'autres types de
widgets sont utilisés : "spinbox", "scale", case à cocher, bouton radio, zone de liste.

G) LE RENDU

III. LES FRAMES


On peut diviser la fenêtre en différentes zones appelées "frames" (cadres). Chaque cadre contient des
éléments.
Thème : page d'accueil d'une application pour laquelle l'utilisateur doit être inscrit.

L'utilisateur doit donc se connecter ou s'inscrire, si c'est sa première visite.

H) LE CODE

# nom programme : test_tkinter4.py


# objet : fenêtre avec deux frames
from tkinter import *

# Création d'un objet "fenêtre"


fenetre = Tk() # nouvelle instance de Tk
fenetre.title("Connexion / inscription ")
fenetre.geometry("900x600")
fenetre.config(bg ="white")

f1 =LabelFrame(fenetre,bd=2, text ="connexion", bg ="skyblue", relief="groove")


f2= LabelFrame(fenetre,bd=2, text ="inscription", bg ="skyblue", relief="groove")
f1.pack(side =LEFT, padx =20, pady=20)
f2.pack(side =RIGHT,padx =20, pady=20)

e1 = Label(f1, text ="identifiant ? ").pack(padx =20, pady=20)


zt1 = Entry(f1,width =50).pack(padx =20, pady=20)
e2 = Label(f1, text ="mot de passe ? ").pack(padx =20, pady=20)
zt2 = Entry(f1,width =50).pack(padx =20, pady=20)

e3 = Label(f2, text ="identifiant ? ").pack(padx =20, pady=20)


zt3 = Entry(f2,width =50).pack(padx =20, pady=20)

e4 = Label(f2, text ="confirmer identifiant ! ").pack(padx =20, pady=20)


zt4 = Entry(f2,width =50).pack(padx =20, pady=20)

e5 = Label(f2, text ="mot de passe ? ").pack(padx =20, pady=20)


zt5 = Entry(f2,width =50).pack(padx =20, pady=20)

e6 = Label(f2, text =" confirmer mot de passe ! ").pack(padx =20, pady=20)


zt6 = Entry(f2,width =50).pack(padx =20, pady=20)

fenetre.mainloop()

I) ANALYSE DU CODE
Le code est un peu lourd, mais en fait il s’écrit très rapidement car il y a 6 étiquettes et 6 zones de texte
pratiquement identiques pour leurs arguments.

f1 =LabelFrame(fenetre,bd=2, text ="connexion", bg ="skyblue", relief="groove") : définition d'un cadre,


enfant de "fenetre", borduré avec l'étiquette "connexion", couleur de fond : "skyblue".

Il existe aussi la méthode frame() mais qui ne prévoit pas d'étiquette.

f1.pack(side =LEFT, padx =20, pady=20) : le frame "f1" est positionné à gauche avec des marges par rapport
à son parent : "fenetre".

e1 = Label(f1, text ="identifiant ? ").pack(padx =20, pady=20) : chaînage de deux méthodes pour définir une
étiquette enfant de "f1" et la positionner avec des marges par rapport au parent.
J) LE RENDU

IV. RÉCUPÉRER DANS UNE FONCTION LES SAISIES DANS DES CHAMPS
Thème : via une interface l'utilisateur saisit x et n dans des champs et en retour il y a affichage de x à la
puissance n dans un troisième champ.

Une fonction doit donc être capable de récupérer les saisies dans des zones de texte et injecter le résultat
dans une troisième ...

K) LE CODE
# nom programme : test_tkinter3.py
# objet du programme : élever x à la puisssance n
from tkinter import *
from math import *

def fpuissance():
x = zt1.get()
n = zt2.get()
resultat = pow(eval(x), eval(n))
zt3.delete(0,END)
zt3.insert(0,resultat)

# ------ fin fonction

# Création d'un objet "fenêtre"


fenetre = Tk() # nouvelle instance de Tk
fenetre.title("Elever x à la puissance n ")
fenetre.geometry("400x400")

fenetre.config(bg ="lime")
for i in range(1,5):
fenetre.rowconfigure(i, pad =20)
fenetre.columnconfigure(1,pad = 20)
fenetre.columnconfigure(2, pad =20)

# pour saisir x
e1 = Label(fenetre, text = " valeur de x ? ")
e1.grid(row=1, column=1)
zt1 = Entry(fenetre, width=30)
zt1.grid(row=1, column=2)

# pour saisir n

e2 = Label(fenetre, text = "valeur de n ? ")


e2.grid(row=2, column=1)
zt2 = Entry(fenetre, width=30)
zt2.grid(row=2, column=2)

# Bouton de commande
b1 = Button(fenetre, text = "Calcul", command=fpuissance)
b1.grid(row=3, column=2)

# pour afficher le résultat


e3 = Label(fenetre, text = "x à la puissance n = ")
e3.grid(row=4, column=1)
zt3 = Entry(fenetre, width=30)
zt3.grid(row=4, column=2)

fenetre.mainloop()

L) ANALYSE DU CODE
Un objet de type "Button" peut avoir comme argument "command =nomFonction"

Le code du programme principal ne présente aucune difficulté c'est seulement du design donc une syntaxe
déja vue.

Ici le bouton de commande appelle la fonction "fpuissance".

Étudions le code de la fonction qui comprend toutes les nouveautés.

x = zt1.get() : récupération du contenu du champ "zt1" dans la variable x

n = zt2.get() : la variable n de la fonction récupère le contenu du champ "zt2"

resultat = pow(eval(x), eval(n)) : x et n sont convertis en numérique avant d'être les arguments de la
méthode pow(). N'oubliez pas d'importer le module math.

zt3.delete(0,END) : effacer le contenu du champ "zt3"

zt3.insert(0,resultat) : insertion du contenu de la variable resultat dans le champ "zt3"

Une zone de texte (ou champ) connait donc trois méthodes utiles :

• get() : récupère le contenu du champ

• delete(de, à) : pour effacer le contenu d'un champ

• insert(position,valeur) : pour insérer dans un champ


M) LE RENDU

N) EXERCICE : UNE CALCULATRICE BASIQUE


Réalisez une calculatrice basique : les 5 opérations de base : addition, multiplication, soustraction, division,
élévation à la puissance.

• CE QUE VOUS DEVEZ OBTENIR

Structurer bien votre programme :

• Cinq fonctions pratiquement identiques : une par bouton de commande

• Un programme principal avec la description de l'interface : 3 étiquettes, 3 zones de texte et 5


boutons de commande

• EXTRAIT DU PROGRAMME
Cette partie du programme vous montre comment créer une fenêtre non redimensionnable et aussi
comment personnaliser les légendes des widgets.

Ci-dessous début du programme principal :


#programme principal
from tkinter import *
# Création d'une interface graphique
fenetre = Tk() # nouvelle instance de Tk
fenetre.title("Calculatrice ")
fenetre.geometry("900x300")
fenetre.resizable(False, False) # l'interface n'est pas redimensionnable
fenetre.config(bg ="lime")
for i in range(1,6):
fenetre.rowconfigure(i, pad =10)
for i in range(1,5):
fenetre.columnconfigure(i, pad =15)
mafonte = "{courier new} 14"
...
# pour saisir A
e1 = Label(fenetre, text = " saisir A", font =mafonte)
zt1 = Entry(fenetre, width=15,font =mafonte)

L'instruction fenetre.resizable(False, False) : La fenêtre ne peut être redimensionnée ni en hauteur, ni en


largeur.

mafonte = "{courier new} 14" : je définis un objet "font" dénommée "mafonte".

e1 = Label(fenetre, text = " saisir A", font =mafonte) : à chaque widget j'ajoute l'option "font = mafonte" afin
que la taille des textes soit plus grande.

zt1 = Entry(fenetre, width=15,font =mafonte) : évitez des champs de saisie trop larges.

V. RÉCUPÉRER LES SAISIES VIA DES BOUTONS RADIO, CASE À COCHER ET ZONES DE LISTE
Dans l'exemple précédent nous avons récupéré dans une fonction les contenus de deux zones de texte
(champs) via la méthode get().

Pour récupérer les saisies effectuées dans des widgets de type cases à cocher, boutons radio et zones de
liste c'est un peu plus compliqué. Le programmeur doit utiliser des variables spécifiques à tKinter dites
variables de contrôle.

O) VARIABLES DE CONTRÔLE
Tkinter utilise des variables de contrôles pour réaliser de nombreuses fonctionnalités, par exemple :

• Une case à cocher (Checkbutton) utilise une variable de contrôle pour mémoriser leur état courant
(on ou off)

• Un groupe de boutons radio (radiobutton) partage une variable de contrôle qui peut être utilisée
pour connaitre le bouton qui est actuellement coché

Pour obtenir une variable de contrôle, il faut utiliser l’un des constructeurs, en fonction du type de
valeur que vous souhaitez mémoriser :

• v_c = DoubleVar() : mémorise un flottant; sa valeur par défaut est 0

• v_c = IntVar() : mémorise un entier; sa valeur par défaut est 0

• v_c = StringVar() : mémorise une chaîne de caractères; sa valeur par défaut est ''

Toutes les variables de contrôle disposent des méthodes :

• get() : retourne la valeur courante de la variable de contrôle

• set(valeur) : modifie la valeur courante de la variable de contrôle

P) LE CODE
# nom programme : test_tkinter5.py
# objet : traitement d'un groupe de boutons radio, cases à cocher, liste
def mafonction():
monpoids = vc1.get()
monsexe =vc2.get()
belote = vc3.get()
tarot = vc4.get()
bridge = vc5.get()
print ("mon poids :", monpoids)
print("mon sexe : ", monsexe)
print("belote : ", belote)
print("tarot : ", tarot)
print("bridge : ", bridge)
index = liste1.curselection()
item= liste1.get(index)
print ("sport : ", index, item)

# programme principal avec design de la fenêtre


from tkinter import *
# définition de la fenêtre
fenetre = Tk() # nouvelle instance de Tk
fenetre.title("Fiche de renseignements")
fenetre.geometry("900x600")
fenetre.config(bg ="skyblue")
for i in range(1,6):
fenetre.rowconfigure(i, pad =20)

# un scale
vc1 = IntVar()
e2 = Label(fenetre, text = "Votre poids ? ")
scale1 = Scale(fenetre, from_=40, to=100, showvalue=True, label='kilos' ,orient='h',
variable =vc1)
e2.grid(row =2, column =1)
scale1.grid(row =2, column =2)

# deux radiobutton
vc2 =StringVar()
e3 = Label(fenetre, text = "Votre sexe ? ")
rb1 = Radiobutton(fenetre, text="femme" , value ="féminin", variable = vc2)
rb2 = Radiobutton(fenetre, text="homme", value ="masculin",variable =vc2)
e3.grid(row =3, column =1)
rb1.grid(row =3, column =2)
rb2.grid(row =3, column =3)

# trois cases à cocher


vc3 =IntVar()
vc4 =IntVar()
vc5 =IntVar()
e4 = Label(fenetre, text = "Jeux de cartes pratiqués ? ")
cc1 = Checkbutton(fenetre, text="belote", variable =vc3)
cc2 = Checkbutton(fenetre, text ="tarot",variable =vc4)
cc3 = Checkbutton(fenetre, text ="bridge",variable =vc5)
e4.grid(row =4, column =1)
cc1.grid(row =4, column =2)
cc2.grid(row =4, column =3)
cc3.grid(row =4, column =4)

# une zone de liste


e5 = Label(fenetre, text = "sport premier pratiqué ? ")
items =Variable(fenetre, ("aucun", "tennis", "vélo", "foot", "natation", "autre"))
liste1 = Listbox(fenetre, listvariable=items)
e5.grid(row =5, column =1)
liste1.grid(row =5, column =2)

# un bouton de commande
bouton1 = Button(fenetre, text = "Récupérez les valeurs saisies", command=mafonction)
bouton1.grid(row=6, column=2)

fenetre.mainloop()

Notez que la fonction comprend des instructions "print". Donc les sorties se feront dans la fenêtre Shell de
l'IDLE.

Q) LE RENDU
• L'INTERFACE GRAPHIQUE

• LA FENÊTRE SHELL DE L'IDLE


mon poids : 68
mon sexe : masculin
belote : 0
tarot : 1
bridge : 0
sport : (4,) natation

R) ANALYSE DU CODE
• COMMENÇONS PAR LE PROGRAMME PRINCIPAL
5 variables de contrôle sont déclarées et nommées "vc1, ... vc5".

"vc1" est relié au widget "scale" et mémorise un entier.

scale1 = Scale(fenetre, from_=40, to=100, showvalue=True, label='kilos' ,orient='h', variable =vc1) : dans les
arguments de Scale() j'ai rajouté "variable =vc1".

"vc2" est relié au groupe de boutons radio et mémorise une chaîne.

rb1 = Radiobutton(fenetre, text="femme" , value ="féminin", variable = vc2) : pour les boutons radio "rb1"
et "rb2" j'ai rajouté dans la méthodeRadiobutton() l'argument "variable =vc2"

Notez bien que pour chaque bouton radio il y a l'argument "value = valeur". Donc si vous sélectionnez "rb1"
vous saisissez en fait "féminin" et si vous sélectionnez "rb2" vous saisissez "masculin".

Il y a trois cases à cocher, il faut donc définir trois variables de contrôle qui mémorise un entier (1 ou 0 selon
que la case est cochée ou pas) : "vc3, vc4, vc5"
cc1 = Checkbutton(fenetre, text="belote", variable =vc3) : dans chacune des trois cases à cocher il faut
rajouter dans les arguments de Ckeckbutton() : "variable = nomVariableControle".

bouton1 = Button(fenetre, text = "Récupérez les valeurs saisies", command=mafonction) :

sur clic sur le bouton de commande, la fonction "mafonction" est appelée.

• ANALYSE DE CETTE FONCTION


Il faut récupérer les valeurs de contrôle dans des variables de la fonction.

monpoids = vc1.get() : récupération du contenu de "vc1" dans variable de fonction "monpoids"

monsexe =vc2.get() : récupération du contenu de "vc2" dans variable de fonction "monsexe"

belote = vc3.get(): récupération dans vc3 de 1 ou zéro. Même remarque pour vc4 et vc5

index = liste1.curselection() : si, dans la liste, on sélectionne la cinquième ligne, la variable "index" récupère
4 grâce à la méthode curselection().

item= liste1.get(index) :la variable "item" récupère l'item d'indice 4 donc "natation".

VI. AMÉLIORATION DU PROGRAMME


Pour les jeux de cartes pratiqués, à la place des 1 ou zéro (coché ou décoché) il est préférable d’utiliser une
chaîne du genre : tarot bridge. Les informations saisies doivent s'afficher dans une zone de texte de
l'interface. La taille des caractères doit être plus grande .

S) EXTRAIT DU PROGRAMME PRINCIPAL MODIFIÉ


...
mafonte = "{courier new} 10 bold "
...
e1 = Label(fenetre, text = "Fiche de renseignements ", font = mafonte)
e1.grid(row =1, column =2)
...
scale1 = Scale(fenetre, from_=40, to=100, showvalue=True, label='kilos' ,orient='h',
variable =vc1, font=mafonte)
...
# trois cases à cocher
vc3 =StringVar()
vc4 =StringVar()
vc5 =StringVar()
e4 = Label(fenetre, text = "Jeux de cartes pratiqués ? ")
cc1 = Checkbutton(fenetre, text="belote", onvalue = "belote", variable =vc3)
cc2 = Checkbutton(fenetre, text ="tarot",onvalue ="tarot", variable =vc4)
cc3 = Checkbutton(fenetre, text ="bridge", onvalue = "bridge",variable =vc5)
...
# pour afficher le résultat
e6 = Label(fenetre, text = "vos informations : ")
e6.grid(row=6, column=1)
zt1 = Entry(fenetre, width=40)
zt1.grid(row=6, column=2)

T) COMMENTAIRE
mafonte = "{courier new} 12 bold " : définit un objet "fonte".

e1 = Label(fenetre, text = "Fiche de renseignements ", font = mafonte) : à chaque widget l'option font =
mafonte est ajoutée.
Pour chaque case à cocher, un argument à la méthode checkbutton() est ajouté. Exemple : onvalue =
"belote"

Donc si la case est cochée la valeur retournée n'est plus 1 mais la valeur de l'argument onvalue.

Donc les trois variables de contrôle associées aux "Checkbutton" doivent changer de type puisqu'elles
doivent désormais retourner une chaîne.

zt1 = Entry(fenetre, width=40, font =mafonte) : ajout d'une zone de texte large (40px) qui va afficher la
chaîne retournée par la fonction.

U) EXTRAIT DE LA FONCTION MODIFIÉ (DERNIÈRES LIGNES)


...
resultat = str(monpoids) + " " + " " + monsexe +" " + belote + " " + tarot + "
"+ " " + bridge + " " + item
zt1.delete(0,END)
zt1.insert(0,resultat)

Les variables "belote", "tarot", "bridge" contiennent désormais une chaîne ou zéro (si case non cochée).

V) LE RENDU

Il aurait été judicieux d'utiliser pour les cases à cocher l'option "offvalue" également.

Dans chacune des trois "Checkbutton" on rajoute :Checkbutton( ... , offvalue =" ", ...) . Ainsi si la case en
question n'est pas cochée on récupère une chaîne vide.

VII. DESSINER DANS UNE INTERFACE GRAPHIQUE


Avec la méthode Canvas() vous pouvez créer dans une fenêtre une zone de dessin. Ce canevas peut
comprendre des formes géométriques mais aussi des images matricielles. Un canevas est un rectangle
ayant pour origine le coin supérieur gauche.
W) UN PROGRAMME QUI CRÉE UN CANEVAS
Dans la fenêtre on dessine un canevas et on insère dedans un image GIF et du texte au-dessus de l'image.
L'image doit être centrée dans le canevas, ses dimensions : celles du canevas /2.

• LE CODE DU PROGRAMME
# nom programme : test_canvas1.py
from tkinter import *
# définition de la fenêtre
fenetre = Tk() # nouvelle instance de Tk
fenetre.geometry("600x400")
fenetre.config(bg ="skyblue")
fenetre.title("Insertion d'un canevas dans la fenêtre")
w = 300
h =300
mafonte = "{courier new} 14 bold "

# insertion d'un canevas


canevas = Canvas(fenetre, width=w, height=h, bg='yellow')
monGif = PhotoImage(file="ordinateur.gif")
# cette image est dans le même dossier que le fichier.py
canevas.create_image(w/2, h/2, image=monGif)
# l'objet de type "Canvas" est stocké dans la variable 'canevas'
canevas.create_text(w/2, h/2, text="Tkinter, c'est super !", font =mafonte,
fill="navy")
canevas.pack()

fenetre.mainloop()
• ANALYSE
canevas = Canvas(fenetre, width=w, height=h, bg='yellow') : création d'un objet de type "Canvas" dans la
fenêtre et qui est stocké dans la variable "canevas". Trois arguments obligatoires : parent, width, height).

monGif = PhotoImage(file="ordinateur.gif") : sélection de l'image gif à insérer avec la méthode


PhotoImage(file =chemin de l'image)

canevas.create_image(w/2, h/2, image=monGif) : insertion dans le canevas de l'image avec la méthode


create_image(). Les arguments sont : X, Y, image. X et Y sont les coordonnées de l'ancrage.

Par défaut l'image est centrée par rapport à ce point d'ancrage (anchor ="center")

canevas.create_text(w/2, h/2,text="Tkinter, c'est super !", font =mafonte, fill="navy") : insertion dans le
canevas d'un texte. Les attributs obligatoires sont : X, Y et text. X et Y sont les coordonnées du point
d'ancrage.

Par défaut le texte est centré par rapport à ce point d'ancrage (anchor ="center").

L'attribut anchor peut prendre d'autres valeurs : nw, n,ne,e,se, sw,w c'est à dire les points cardinaux.

Un conseil : les images à insérer et le programme (fichier .py) dans le même répertoire !
• LE RENDU

• REMARQUE
Pour insérer, dans un canevas, des images d'autres formats (.jpeg, png), il faudra passer par le
module PIL (qui n'est pas présent par défaut dans Python).

X) DESSINER DES FORMES DANS UN CANEVAS


• DES MÉTHODES
Si l'objet de type Canvas est référencé par la variable "canevas" les syntaxes sont :

• Pour dessiner un rectangle : canevas.create_rectangle(x0, y0, x1, y1). (x0, y0, x1, y1) sont les


coordonnées des sommets opposés du rectangle.

• Pour dessiner une ellipse : canevas.create_oval(x0, y0, x1, y1). (x0, y0, x1, y1) sont les coordonnées


des sommets opposés du rectangle dans lequel est tracée l'ellipse.

• Pour dessiner un segment : canevas.create_line(x0, y0, x1, y1)

Attributs optionnels :

• width : épaisseur du contour, en pixels.

• outline : la couleur du contour.

• fill : couleur de remplissage

Thème : Un programme qui dessine dans un canevas le logo de l'entreprise.

• LE CODE
# nom programme : test_canvas2.py
#fenetre avec logo de l'entreprise
from tkinter import *
# définition de la fenêtre
fenetre = Tk() # nouvelle instance de Tk
fenetre.geometry("900x600")
fenetre.config(bg ="skyblue")
fenetre.title("Insertion d'un canevas dans la fenêtre")
# dimensions minimales des ligne et colonne zéro
fenetre.rowconfigure(0,minsize =30)
fenetre.columnconfigure(0,minsize =30)
w = 250
h =150
mafonte = "arial 12 bold "
# insertion d'un canevas
canevas = Canvas(fenetre, width=w, height=h)
rect1 = canevas.create_rectangle(0, 0, w, h, fill ="blue")
canevas.create_oval(w/10, h/10, w*9/10, h*9/10, fill ="red", outline ="white", width
=8)
canevas.create_text(w/2, h/2, text="Francemeubles.com", font =mafonte, fill="white")
canevas.grid(row =1, column=1)
• ANALYSE DU CODE
fenetre.rowconfigure(0,minsize =30)

fenetre.columnconfigure(0,minsize =30) : la ligne et la colonne 0 ont une largeur / hauteur de 30px. Le


canevas va en effet être positionné avec la méthode grid().

Le rectangle occupe tout le canevas et est rempli de bleu.

Une ellipse de fond rouge avec une bordure blanche épaisse se superpose.

Un texte ancré au milieu du canevas a des caractères blancs.

• LE RENDU

Vous aimerez peut-être aussi