La console, c’est simple mais c’est moche. Il nous reste à voir comment concevoir un code qui permet de réaliser des choses mais en présentant les éléments de façon plus jolie.
Pour cela, nous allons aujourd’hui utiliser un nouveau module : le module Tkinter pour « Tk interface ».
Pas besoin de l'importer avec l'instruction pip : il est intégré de base à la distribution Python.
On l’appellera à l’aide de la commande suivante :
from tkinter import *
Je n'utilise pas d'alias comme avec Pillow : nous allons trop régulièrement taper le nom du module sinon.
Cette partie est assez directive de façon à pouvoir y revenir en cours de formation. Les solutions sont souvent données directement avec le code correspondant. Vous aurez tout le temps de vous y mettre lors des projets.
Vous aller créer votre première fenêtre graphique et y insérer un Label (avec un L majuscule) et il est créé avec la méthode-constructeur qui porte le même nom (Label() ) : il s’agit d’une zone dans laquelle on pourra insérer un texte ou une image.
(nom dans le domaine informatique d’un « gadget » graphique). Ce premier widget est de classe01° Recopier puis lancer le code suivant :
from tkinter import *
fen_princ = Tk()
Label(fen_princ, text = "C’est ici que j’affiche mon premier texte !")
=pack()
.fen_princ.mainloop()
Quelques explications sur les cinq lignes précédentes :
from tkinter import *
Importation du module tkinter qui contient les classes "Widgets" …
fen_princ = Tk()
On crée un objet-fenêtre graphique à l’aide de la méthode constructeur Tk() et on le nomme fen_princ (pour fenêtre principale). Si on n’a pas importé le module tkinter avant, Python ne trouvera pas Tk() et va donc déclarer une erreur.
Label(fen_princ, text = "C’est ici que j’affiche mon premier texte !")
=On crée un objet-label qui se nomme Label sont :
. Les attributs dupack()
.On utilise la méthode pack() sur l’objet-label : cela place l’objet dans la fenêtre donnée lors de la création : fen_princ ici.
fen_princ.mainloop()
On crée une boucle sur la fenêtre fen_princ pour qu’elle surveille en permanence ce qui s’y passe. C'est comme si vous aviez demandé de surveiller en permanence ce qui se passe sur cette fenêtre, tant que la fenêtre reste ouverte.
02° Créer deux autres objets-labels de type text et les faire apparaître dans votre fenêtre.
Il existe d’autres attributs qu’on peut utiliser :
Label(fen_princ, text = "Mon texte ici !", fg = "red")
=
Affiche le texte en rouge (fg pour foreground, premier plan).
Label(fen_princ, text = "Mon texte ici !", fg = "yellow", bg = "black")
=
Affiche le texte en jaune (fg pour foreground, premier plan) sur fond noir (bg pour background, arrière plan).
Label(fen_princ, text = "C’est ici que j’affiche mon premier texte !" , font = ("Helvetica", 32))
=
Affiche le texte en définissant un 2-uplet (type de police, taille de police) pour le font(police) : ici Helvetica pour le type de police et 32 pour la taille de police. Attention, on doit donc fournir les données à travers un tuple (d'où les parenthèses).
03° Tester les attributs présentés pour modifier vos trois textes.
04° Modifier l’un des textes pour qu’il soit très, très long. Relancer. Voyez-vous le problème ?
Nous apprendrons à résoudre ce problème dans l'activité suivante. Pour l'instant, tentez de ne pas trop chercher à remplir vos Labels.
Label, Image ou Img avec une majuscule, et int ou float avec une minuscule ? Pourquoi ?
Ce n’est pas le fruit du hasard : le type d’une variable commence par une minuscule et la classe d’un objet par une majuscule. Ca évite de se tromper.
Et la méthode constructeur d'un objet est le nom de la classe : ainsi si la classe se nomme Label, son constructeur sera Label() avec les parenthèses.
Ou : c’est quoi à la fin une « classe » ?
Vous avez déjà manipulé plusieurs fois les classes via les objets.
Variables de structure :
Pour rappel, nous avons parfois utilisé des variables dont le type est int (on stocke un entier) ou float (on stocke un réel).
Par exemple :
a = 45
On stocke deux choses en mémoire :
a est donc une variable "simple" qui ne contient que la valeur d’un seul type de donnée. On parle de variable de structure car la structure des données est prédéfinie. Elle ne peut contenir qu'un nombre bien précis et prédéterminé de données. Un integer, un float, un string...
Lorsque l'interpréteur tombe sur a, il va donc pouvoir vous afficher la valeur à l'intérieur de cette "case-mémoire".
Si on supprime les références, on obtient la vision des "boites" :
Variables de référence :
Il existe néanmoins des objets plus complexes, comme les images ou les widgets. Une image est une entité beaucoup plus complexe qu’un entier : elle est définie par :
mon_image = Img.open("linux.jpg")
De plus, les objets-image Pillow possèdent des méthodes bien spécifiques (l'activité sur les images devrait vous en rappeler quelques unes : show, putpixel, getpixel, save).
Ici l'utilisation de la variable mon_image ne renvoie pas directement une valeur mais une référence (une adresse) vers les données de l'objet. Cette référence va ensuite être utilisée pour obtenir la bonne valeur parmi toutes celles stockées pour l'objet.
On peut donc voir un objet comme :
Si on supprime les références, l'imbrication devient plus facile à visualiser :
Voilà. Vous savez maintenant pourquoi on utilise des noms différents pour désigner des choses qui ont l'air assez semblables si on n'y regarde pas de près. On a donc :
Des types de variables pour les variables "simples" ou de structures :
x = 45
Des classes pour les variables-objet ou variables de référence:
monAffichage = Label(fen_princ, text = "C’est ici que j’affiche mon premier texte !")
Et si on veut lire le contenu d'un attribut, on peut ?
Et bien oui. Il faut utiliser la méthode cget sur votre widget.
from tkinter import *
fen_princ = Tk()
Label(fen_princ, text = "Mon texte ici !", fg = "red")
=pack()
.print(cget('fg'))
.fen_princ.mainloop()
Si vous lancez le code, vous obtiendrez ceci dans la console :
red
05° Rajouter la ligne de code permettant d'afficher le texte qui va être affiché dans ce widget.
Mais on peut faire mieux : on peut également configurer par un code la valeur d'un attribut. Il faut dans ce cas utiliser la méthode config sur le widget correspondant.
A titre d'exemple, voici un code qui affecte une variable couleur puis qui l'affecte à l'attribut fg de deux widgets. Ainsi, la modification de cette variable permet de modifier la couleur des deux widgets d'un coup. On fait la même chose avec la largeur du widget (via l'attribut height).
from tkinter import *
fen_princ = Tk()
Label(fen_princ, text = "Premier texte")
=Label(fen_princ, text = "Second texte")
=pack()
.pack()
.couleur = 'blue'
config(fg=couleur)
.config(fg=couleur)
.fen_princ.mainloop()
06° Créer un variable fond, affecter un string correspondant à une couleur puis modifier les deux labels pour que leur background correspondent à fond.
...CORRECTION...
from tkinter import *
fen_princ = Tk()
Label(fen_princ, text = "Premier texte")
=Label(fen_princ, text = "Second texte")
=pack()
.pack()
.couleur = 'yellow'
config(fg=couleur)
.config(fg=couleur)
.fond = 'black'
config(bg=fond)
.config(bg=fond)
.fen_princ.mainloop()
Pour pourriez obtenir le même résultat en utilisant la méthode configure. Je préfère noter config car c'est plus court mais c'est vous qui voyez...
Et si on veut afficher un texte variable en fonction des moments ? On peut ? Oui, on peut. Il existe même deux façon de gérer cela.
La première façon, vous la connaissez déjà. Il suffit d'utiliser la méthode config.
Voici un exemple pour la forme : on crée trois Labels et on leur demande d'afficher le même texte.
from tkinter import *
fen_princ = Tk()
Label(fen_princ, text = "Premier texte")
=Label(fen_princ, text = "Second texte")
=Label(fen_princ, text = "Troisième texte")
=pack()
.pack()
.pack()
.monTexte = 'Voici le texte à mettre à jour'
config(text=monTexte)
.config(text=monTexte)
.config(text=monTexte)
.fen_princ.mainloop()
07° Utiliser le code pour vérifier que cela fonctionne.
Ca fonctionne. Mais le module Tkinter possède un moyen plus efficace de mettre à jour automatiquement les Labels texte si le texte à afficher change justement. C'est pratique pour les applications où un même champ peut être affiché à différents endroits. Ca évite d'oublier l'un des labels.
La deuxième méthode consiste à utiliser l’attribut textvariable qu'on doit remplir avec un objet de classe StringVar, à savoir une sorte de String qui, lorsqu'il change de valeur, provoque automatiquement la modification d'affichage du widget (ou des widgets !) auquel il est rattaché.08° Lancer le code suivant :
from tkinter import *
fen_princ = Tk()
monTexte = StringVar()
monTexte.set("Hello World !")
Label(fen_princ, textvariable = monTexte)
=pack()
.monTexte.set("Bonjour le Monde !")
fen_princ.mainloop()
Ligne 3 monTexte = StringVar()
: On voit qu’on déclare un objet de classe StringVar : c’est une classe de tkinter
contenant un string ayant la particularité d’informer le programme lorsque son contenu change.
Ligne 4 monTexte.set("Hello World !")
: On utilise la méthode set(…) pour lui affecter un contenu.
Ligne 5 Label(fen_princ, textvariable = monTexte)
: On définit l’objet-Label = dans lequel on déclare monTexte en tant qu’attribut textvariable.
Ligne 6 pack()
: On active . dans la fenêtre fen_princ.
Ligne 7 monTexte.set("Bonjour le Monde !")
: On modifie monTexte APRES qu’il se soit affiché à l’écran pour la première fois.
Ligne 8 fen_princ.mainloop()
: On surveille la fenêtre fen_princ et on laisse tourner.
On remarque qu’à l’écran c’est bien le second texte qui apparaît.
09° Lancer le code suivant qui permet de modifier trois labels simplement en modifiant le contenu du StringVar !
from tkinter import *
fen_princ = Tk()
monTexte = StringVar()
monTexte.set("Hello World !")
Label(fen_princ, textvariable = monTexte)
=pack()
.Label(fen_princ, textvariable = monTexte)
=pack()
.Label(fen_princ, textvariable = monTexte)
=pack()
.monTexte.set("Bonjour le Monde !")
fen_princ.mainloop()
Vous devriez obtenir ceci :
Quel est l'intérêt d'utiliser des StringVar par rapport à une modification à la rude via un config ? Et bien, vous êtes certain que tous les widgets qui dépendent de votre texte seront modifiés automatiquement. Ca évite d'en oublier un.
En utilisant l'attribut TEXT
On utilise l'attribut text qui doit contenir un String. On doit alors utiliser la méthode config sur le . Par exemple :
config(text='Nouvel affichage !')
.Si on veut lire le contenu du Label, on doit alors utiliser la méthode cget. Exemple :
print( cget('text') )
.Cette ligne afficherait ici :
Nouvel affichage !
En utilisant l'attribut TEXTVARIABLE
On utilise l'attribut textvariable qui doit contenir un StringVar(). On doit alors utiliser la méthode set sur l'objet StringVar pour modifier automatiquement l'affichage du widget.
monTexte = StringVar()
monTexte.set("Hello World !")
Label(fen_princ, textvariable = monTexte)
=monTexte.set("Bonjour le Monde !")
D'ailleurs, si on veut lire le contenu de l'affichage, il faut également du coup aller voir le contenu du StringVar à l'aide de la méthode get :
print( monTexte.get() )
Cette ligne afficherait ici :
Bonjour le Monde !
Le problème des langages de haut niveau, c'est qu'il existe souvent plusieurs façons de faire les choses. Normalement la méthode get doit être appliquée au StringVar. Mais le module Tkinter peut également comprendre ce que vous voulez si vous utiliser cette méthode sur un Label qui contient un textvariable...
print( get() )
.Cette ligne afficherait ici :
Bonjour le Monde !
Voilà pour un premier tour des fonctionnalités des labels text.
Tout d’abord, remarquons qu’on utilise Button, avec un B majuscule. C’est normal : c’est une classe, pas un type de variable.
Devinez comment se nomme sa méthode-constructeur... Button().
Notre programme manque un peu d’interactivité pour l’instant. Nous allons donc créer un bouton qui va enclencher la modification d’un texte affiché.
Attention néanmoins : nous allons devoir utiliser un nouveau concept : la fonction.
C’est simple : il s’agit de lignes de codes qui ne s’activent que lorsqu’on les appelle. Et on peut les appeler autant de fois qu’on veut, il suffit de taper le code une seule fois. Exemple :
def mise_a_jour():
monTexte.set("Et voilà !")
On crée une fonction en Python à l’aide du mot clé def (comme définition) def mise_a_jour():
.
On doit nécessairement faire suivre le nom de la fonction de () (nous verrons pourquoi plus tard ) : def mise_a_jour():
.C'est le fait qu'on trouve () ou (blabla) après une chaîne de caractères qui nous indique qu'on a une fonction ou une méthode (une fonction de classe).
Attention, les instructions qui doivent s’exécuter doivent être tabulées (touche TAB) pour que Python comprenne qu’elles font partie de la fonction. Il est donc vital de bien tabuler votre code. Dans Notepad++, on peut faire s'afficher les tabulations à l'aide du menu AFFICHAGE - SYMBOLES SPECIAUX - AFFICHER ESPACES ET TABULATIONS
Dernier point vital : on finit la définition de la fonction par :: def mise_a_jour():
. Cela indique à Python que c'est à partir de là qu'il doit surveiller les tabulations.
10° Lancer le code suivant :
# -*-coding:Utf-8 -*
from tkinter import *
# - - - - - - - - - - - - - - - - - -
# Déclarations des fonctions utilisées
# - - - - - - - - - - - - - - - - - -
def mise_a_jour():
monTexte.set("Et voilà !")
# - - - - - - - - - - - - - - - - - -
# Création de la fenêtre et des objets associés la fenêtre
# - - - - - - - - - - - - - - - - - -
fen_princ = Tk()
# Création d'un Label nommé monAffichage ayant monTexte comme textvariable
monTexte = StringVar()
monTexte.set("Texte de base !")
Label(fen_princ, textvariable = monTexte)
=pack()
.# Création d'un Button lancant la fonction mise_a_jour
Button(fen_princ, text = "Mise à jour du texte ci-dessus", command=mise_a_jour)
=pack()
.# - - - - - - - - - - - - - - - - - -
# Bouclage de la fenêtre fen_princ
# - - - - - - - - - - - - - - - - - -
fen_princ.mainloop()
Cela donne l'interface ci-dessous qui possède un Button qui permet de modifier le texte :
Que fait le programme ?
def mise_a_jour():
monTexte.set("Et voilà !")
fen_princ = Tk()
) contenant :monTexte = StringVar()
monTexte.set("Texte de base !")
Label(fen_princ, textvariable = monTexte)
=pack()
.Button(fen_princ, text = "Mise à jour du texte ci-dessus", command = mise_a_jour)
=pack()
.Attention : Le nom de la fonction ne comporte pas de « à » mais bien un « a ». C’est plus sain en terme de code.
11° Rajouter une fonction et un bouton de façon à pouvoir faire varier encore une fois le texte du Label.
Si vous bloquez, une possibilité de correction est téléchargeable en cliquant sur l'image:
Remarque : On aurait pu faire ça aussi avec un bouton sans nom :
Button(text = "Mise à jour du texte ci-dessus", command = mise_a_jour).pack()
On obtient donc une ligne de code plutôt que deux :
Button(fen_princ, text = "Mise à jour du texte ci-dessus", command = mise_a_jour)
=pack()
.Attention à ne pas utiliser cette façon de faire si vous avez besoin d'accéder ensuite au widget : avec la déclaration-affichage en une ligne, on ne garde pas en mémoire l'adresse du widget.
Remarque 2 : La console s'affiche encore, c'est pénible. Si vous voulez ne plus l'afficher, il suffit de changer l'extension de votre fichier Python : transformez le .py en .pyw. Le w veut dire without, sans.
Bon, ça commence à ressembler à de l’interactivité. Il reste à enregistrer les données que fournit l’utilisateur.
La partie 1 de ce cours fournissait l’équivalent du print sur la console.
Voyons maintenant l’équivalent du input.
12° Réaliser une interface comportant un Label dans lequel un texte est inscrit en noir. Créer quatre boutons :
La méthode config est bien entendu indispensable.
Tout d’abord, remarquons qu’on utilise Entry avec un E majuscule. C’est normal : c’est une classe, pas un type de variable.
Imaginons que nous voulions remplacer le texte du Label monAffichage par un texte rentré par l’utilisateur. Comment faire ?
Il faut créer un objet de classe Entry qui comme son nom l’indique permettra à l’utilisateur de rentrer des données.
Commençons par le voir en dehors d’un code plus complexe : imaginons qu’on désire connaître le nom que l’utilisateur veut donner à la sauvegarde de son image :
nom_fichier = StringVar()
nom_fichier.set("mp_rgb_1.jpg")
Entry(fen_princ, textvariable = nom_fichier, width=30)
=pack()
.Explications :
Le code ci-dessus crée un objet de classe StringVar nommé nom_fichier et lui affecte la valeur initiale "mp_rgb1.jpg" :
nom_fichier = StringVar()
nom_fichier.set("mp_rgb_1.jpg")
Ensuite, on crée un objet de classe Entry de nom entree_fichier et on voit qu'on tape textvariable = nom_fichier
, pour le lier à l'objet StringVar précédent :
Entry(fen_princ, textvariable = nom_fichier, width=30)
=pack()
.On peut récupérer le contenu textuel du Label comme avec un Label : en allant voir le contenu du StringVar associé à l’aide de la méthode get().
Comme nous l'avons vu plus haut, on peut récupérer le texte de deux façons avec un StringVar :
contenu = nom_fichier.get()
contenu = .get()
13° Créer une fenêtre avec 3 widgets : un Label, un Entry et un Button. En appuyant sur le bouton, on doit changer le contenu textuel du Label en y recopiant le contenu du Entry.
Si vous bloquez, une possibilité de correction est téléchargeable en cliquant sur les images :
Ca commence à être vraiment interactif. En terme de présentation, on notera que la plupart des attributs graphiques de la classe Label existent sur la classe Entry. Taper « Python Tk Entry » pour plus de précision.
Première solution : Sans bouton. On utilise simplement les propriétés des objets de class StringVar et on attache le StringVar à la fois à une Entry et à un Label. Avantage : les modifications sont réalisées en toute simplicité : lorsqu'on modifie le StringVar, le contenu du Label bouge automatiquement aussi.
# -*-coding:Utf-8 -*
from tkinter import *
nom_fichier = StringVar()
nom_fichier.set("mp_rgb_1.jpg")
Label(fen_princ, textvariable = nom_fichier)
=pack()
.Entry(fen_princ, textvariable = nom_fichier, width=30)
=pack()
.Deuxième solution : Avec bouton. Lorsqu'on appuie sur le bouton, on va lire le contenu de l'Entry et on met alors le Label à jour :
# -*-coding:Utf-8 -*
from tkinter import *
# - - - - - - - - - - - - - - - - - -
# Déclarations des fonctions utilisées
# - - - - - - - - - - - - - - - - - -
def mise_a_jour():
monTexte.set( .get())
# - - - - - - - - - - - - - - - - - -
# Création de la fenêtre et des objets associés la fenêtre
# - - - - - - - - - - - - - - - - - -
fen_princ = Tk()
# Création d'un Label nommé monAffichage ayant monTexte comme textvariable
monTexte = StringVar()
monTexte.set("Texte de base !")
Label(fen_princ, textvariable = monTexte)
=pack()
.# Création d'un Entry nommé nom_fichier ayant nom_fichier comme textvariable
nom_fichier = StringVar()
nom_fichier.set("mp_rgb_1.jpg")
Entry(fen_princ, textvariable = nom_fichier, width = 30)
=pack()
.# Création d'un Button lancant la fonction mise_a_jour
Button(fen_princ, text = "BOUTON 1", command = mise_a_jour)
=pack()
.# - - - - - - - - - - - - - - - - - -
# Bouclage de la fenêtre fen_princ
# - - - - - - - - - - - - - - - - - -
fen_princ.mainloop()
On remarquera qu'ici on lit le widget contenant le texte plutôt que le StringVar. Mais les deux façons donnent le même résultat :
monTexte.set( .get())
monTexte.set(nom_fichier.get())
La console apparaît encore ! Pour la faire disparaître, il suffit de changer manuellement l’extension .py en .pyw (le w est pour without, sans en français).
14° Modifier l'extension pour faire disparaitre la console lors de l'exécution.
Si ce n'est pas déjà fait, il faut installer Pillow. Si vous êtes en salle informatique, vous pouvez passer cette installation, c'est déjà installé.
Pour installer Pillow, il faut :
> pip install --upgrade pip
> pip install Pillow
Si ca ne marche pas, je vous laisse aller lire le tutoriel disponible sur notre site :
En réalité, on peut afficher soit du texte soit une image dans les widgets de classe Label.
Il faut d’abord penser à importer les classes Image (ou Img avec un alias) et ImageTk. En effet, la classe Image de base de la bibliothèque PIL n’est pas directement interprétable par les widgets du module Tk. C'est dommage mais c'est comme ça.
from PIL import Image as Img
from PIL import ImageTk
Convertir presentation (un objet Image) en presentationTk (objet ImageTk) est simple :
presentationTk = ImageTk.PhotoImage(presentation)
C'est bête, Tk ne pourra pas travailler directement avec votre objet-image presentation.
Voilà le bout code qui permet d’afficher une image de classe Image(Img) dans Label :
, un widget de classepresentation = Img.new("RGB", (20,20), (255,255,150))
presentationTk = ImageTk.PhotoImage(presentation)
Label(fen_princ, image = presentationTk)
=pack()
.Le code complet :
# -*-coding:Utf-8 -*
from tkinter import *
from PIL import Image as Img
from PIL import ImageTk
# - - - - - - - - - - - - - - - - - -
# Création de la fenêtre et des objets associés la fenêtre
# - - - - - - - - - - - - - - - - - -
fen_princ = Tk()
# Création d'un Label nommé monAffichage
Label(fen_princ, text = "Une belle image", width = 70)
=pack()
.# Création d'une image de base
presentation = Img.new("RGB", (40,40), (0,0,255))
presentationTk = ImageTk.PhotoImage(presentation)
# Création d'un label de type image associé à presentationTk
Label(fen_princ, image = presentationTk)
=pack()
.# - - - - - - - - - - - - - - - - - -
# Bouclage de la fenêtre fen_princ
# - - - - - - - - - - - - - - - - - -
fen_princ.mainloop()
On obtient : (correction en cliquant sur l'image)
15° Tester le code et l'expliquer, ligne par ligne.
Si on veut créer une image variable, c'est un peu plus complexe à cause d'un mécanisme interne de gestion de la mémoire qu'on nomme "ramasse-miettes". En gros, l'ordinateur libère la place mémoire attribuée à des objets dont on ne posséde plus les références. Nous traiterons de cette difficulté dans le chapitre sur la portée des variables dans les fonctions.
Dans cette activité, nous nous contenterons de changer l'image du Label à partir d'une source qui existe déjà dans le programme lui-même. A cause du "ramasse-miettes", afficher une image qu'on crée dans la fonction d'un bouton est beaucoup plus compliqué.
Il suffit donc d'utiliser la méthode config sur l'attribut image du Label.
16° Chercher dans le code suivant l'endroit où on ordonne le changement d'image.
17° Une erreur s'est glissée dans le code. C'est un petit détail dans le nom d'une des variables. Trouvez l'erreur puis réalisez une interface comportant 3 boutons : un bouton Red, un bouton Green et un bouton Blue.
18° Modifier le programme pour que les boutons modifient en plus la couleur du texte qui s'affiche dans le premier Label texte.
# -*-coding:Utf-8 -*
from tkinter import *
from PIL import Image as Img
from PIL import ImageTk
# - - - - - - - - - - - - - - - - - -
# Déclarations des fonctions utilisées
# - - - - - - - - - - - - - - - - - -
def colorierBleu() :
configure(image = presentationBTk)
.def colorierRouge() :
configure(image = presentationRTk)
.# - - - - - - - - - - - - - - - - - -
# Création de la fenêtre et des objets associés la fenêtre
# - - - - - - - - - - - - - - - - - -
fen_princ = Tk()
# Création d'un Label nommé monAffichage
Label(fen_princ, text = "Belle image variable avec le Button", width=70)
=pack()
.# Création d'un Button lancant la fonction colorierBleu()
Button(fen_princ, text = "En bleu !", command = colorierBleu)
=pack()
.Button(fen_princ, text = "En rouge !", command = colorierRouge)
=pack()
.# Création d'une image de base
presentation = Img.new("RGB", (40,40), (50,50,70))
presentationTk = ImageTk.PhotoImage(presentation)
# Création d'une image bleue
presentationB = Img.new("RGB", (40,40), (0,0,255))
presentationBTk = ImageTk.PhotoImage(presentationB)
# Création d'une image rouge
presentationR = Img.new("RGB", (40,40), (0,0,255))
presentationRTk = ImageTk.PhotoImage(presentationB)
# Création d'un label de type image associé à presentationTk
Label(fen_princ, image = presentationTk)
=pack()
.# - - - - - - - - - - - - - - - - - -
# Bouclage de la fenêtre fen_princ
# - - - - - - - - - - - - - - - - - -
fen_princ.mainloop()
Il nous reste deux petites choses à voir :
Pour le premier point, c'est très facile : il faut utiliser la méthode geometry sur le widget :
Voici de quoi créer une fenêtre de dimensions 600 pixels sur 600 pixels :
# -*-coding:Utf-8 -*
from tkinter import *
# - - - - - - - - - - - - - - - - - -
# Création de la fenêtre et des objets associés la fenêtre
# - - - - - - - - - - - - - - - - - -
fen_princ = Tk()
fen_princ.geometry("600x600")
# - - - - - - - - - - - - - - - - - -
# Bouclage de la fenêtre fen_princ
# - - - - - - - - - - - - - - - - - -
fen_princ.mainloop()
Ce code ne crée RIEN sinon une fenêtre Tkinter de largeur 600 px sur une hauteur de 600 pixels :
Pour créer un carré bleu et le déplacer, on peut utiliser la méthode place. Par exemple place(x = 50, y = 100)
sur le widget que vous voulez voir placer aux coordonnées x = 50 ( 50 pixels vers la gauche) et y = 100 (100 pixels vers le bas).
# -*-coding:Utf-8 -*
from tkinter import *
from PIL import Image as Img
from PIL import ImageTk
# - - - - - - - - - - - - - - - - - -
# Création de la fenêtre et des objets associés la fenêtre
# - - - - - - - - - - - - - - - - - -
fen_princ = Tk()
fen_princ.geometry("600x600")
# Création d'une image de base
carreBleu = Img.new("RGB", (40,40), (0,0,255))
carreBleuTk = ImageTk.PhotoImage(carreBleu)
# Création d'un label de type image associé à presentationTk
Label(fen_princ, image = carreBleuTk)
=place(x = 50, y = 100)
.# - - - - - - - - - - - - - - - - - -
# Bouclage de la fenêtre fen_princ
# - - - - - - - - - - - - - - - - - -
fen_princ.mainloop()
On rajoute les bibliothèques Image et ImageTk.
On crée l'image d'un carré bleu avec PIL et on l'utilise pour créer une image ImageTk.
On place cette image dans un Label nommé
.On modifie la position de ce widget avec la nouvelle méthode place
19° Utiliser ces nouvelles connaissances pour créer une sorte de Simon, le jeu des carrés colorés :
C'est clairement perfectible : les carrés ne sont pas centrés par exemple. Nous allons voir d'autres façons de placer les widgets dans une autre activité. Mais vous avez au moins une première manière fonctionnelle de placer les widgets où vous voulez.
20° Dernière action : créer 4 boutons GAUCHE-DROITE-HAUT-BAS : ils devront modifier la position des 4 carrés colorés.
Indications :
Voilà. C'est tout pour une première prise en main. Mais vous avez déjà de quoi faire. Si vous en voulez plus, il vous suffit de vous renseigner à l'aide de la documentation.
Question : Pourquoi mettre les variables faisant référence aux en orange ?
Pour rendre le code plus clair : sur le site, en orange, c'est une variable-objet faisant référence à un widget.
Comme c'est une variable, j'aurai pu simplement les mettre en bleu comme toutes les autres variables. Mais en les placant en orange, on voit plus facilement ce qui est lié à la bibliothèque Tkinter.
De toutes manières, lorsque vous coderez votre propre interface, toutes les variables auront la même couleur.
J'ai donc utilisé ceci :
from tkinter import *
fen_princ = Tk()
Label(fen_princ, text = "C’est ici que j’affiche mon premier texte !")
=pack()
.fen_princ.mainloop()
Mais j'aurai pu également faire commencer les noms par wid_ par exemple :
from tkinter import *
wid_fen_princ = Tk()
wid_monAffichage = Label(wid_fen_princ, text = "C’est ici que j’affiche mon premier texte !")
wid_monAffichage.pack()
wid_fen_princ.mainloop()
J'aurai même pu ne rien mettre, ce sont juste des variables comme les autres. Des variables de référence, mais des variables.
from tkinter import *
fen_princ = Tk()
monAffichage = Label(fen_princ, text = "C’est ici que j’affiche mon premier texte !")
monAffichage.pack()
fen_princ.mainloop()
Question : Les widgets s'affichent les uns en dessous des autres. On peut faire mieux ?
Oui, bien entendu. Par contre, c'est l'objet d'une autre activité. Vous pouvez aller chercher l'activité sur le placement des Widgets sur ce site par exemple. Ou vous renseignez sur l'utilisation des méthodes pack, grid et place sur Internet.