Nous voyons ici comment dessiner des polygones, puis comment les animer un peu.
Définir un rectangle
On définit un rectangle de côtés parallèles à la fenêtre avec create_rectangle
,
on précise pour cela les coordonnées du point supérieur gauche et les coordonnées du sommet opposé (inférieur droit).
Testez le code suivant. Modifiez le pour être certain de bien saisir le rôle des paramètres.
import tkinter
import tkinter.colorchooser
def couleurInterieur() :
""" lance une fenêtre de sélection d'une couleur. Modifie la variable
couleurremplissage avec la couleur choisie."""
global couleurremplissage
c = tkinter.colorchooser.askcolor()
couleurremplissage = c[1]
def couleurContour() :
""" lance une fenêtre de sélection d'une couleur. Modifie la variable
couleurbordure avec la couleur choisie."""
global couleurbordure
c = tkinter.colorchooser.askcolor()
couleurbordure = c[1]
def recolorierRectangle():
""" Modifie les attributs couleurs de rectangle1."""
canevas.itemconfig(rectangle1, fill = couleurremplissage, outline = couleurbordure)
fenetre = tkinter.Tk()
# définition d'une zone de dessin dans la fenêtre tkinter :
largeur = 150
hauteur = 150
canevas = tkinter.Canvas(fenetre, width = largeur, height = hauteur)
canevas.pack()
couleurremplissage = '' # pas de remplissage au départ
couleurbordure = 'black' # frontière noire au départ
# définition d'un rectangle, côtés parallèles à la fenêtre, de sommets haut-gauche A(10,10)
# et de sommet opposé (bas-droit) B(50, 100) :
rectangle1 = canevas.create_rectangle(10,10, 50,100,
fill = couleurremplissage, outline = couleurbordure , width=4)
bouton1 = tkinter.Button(fenetre, text = "Couleur de remplissage", command = couleurInterieur)
bouton1.pack()
bouton2 = tkinter.Button(fenetre, text = "Couleur de contour", command = couleurContour)
bouton2.pack()
bouton3 = tkinter.Button(fenetre, text = "Recolorier le rectangle", command = recolorierRectangle)
bouton3.pack()
fenetre.mainloop()
Un autre exemple est donné ci-dessous pour la création de rectangles. Testez.
import tkinter
import random as rd
# fenêtre principale
fenetre = tkinter.Tk()
# dimensions de l'écran :
ll = fenetre.winfo_screenwidth()
hh = fenetre.winfo_screenheight()
# canvas prenant toute la fenêtre :
canevas = tkinter.Canvas(fenetre, width = ll, height = hh)
canevas.pack()
def rectangleHasard(zone) :
"""
le paramètre zone est de type canvas.
création d'un rectangle de coin supérieur gauche (cx,cy) choisi au hasard
largeur et hauteur du rectangle au hasard
"""
largeur = zone.winfo_reqwidth() # largeur du canvas zone
hauteur = zone.winfo_reqheight() # hauteur du canvas zone
cx = rd.random()*largeur
cy = rd.random()*hauteur
l = rd.random()*largeur/5
h = rd.random()*hauteur/5
zone.create_rectangle(cx,cy, cx+l,cy+h, fill = 'white', outline = 'grey' , width=4)
nbRectangles = 5000
for _ in range(nbRectangles) :
rectangleHasard(canevas)
# attente d'une milliseconde et rafraichissement de l'affichage :
# (sans cela, les rectangles s'affichent tous d'un coup en fin de boucle)
fenetre.after(1,fenetre.update())
fenetre.mainloop()
Définir un polygone
On définit un polygone par create_polygon
.
Les premiers paramètres sont les coordonnées des sommets, chaque sommet est relié au suivant par un segment,
le dernier est relié au premier.
On peut préciser la couleur de remplissage
avec fill
,
la couleur des contours avec outline
,
l'épaisseur du trait de contour avec width
.
import tkinter
fenetre = tkinter.Tk()
# définition d'une zone de dessin dans la fenêtre tkinter :
largeur = 150
hauteur = 150
canevas = tkinter.Canvas(fenetre, width = largeur, height = hauteur)
canevas.pack()
# définition d'un polygone de sommets A(10,10), B(20,20), C(100,50), D(20,100) :
canevas.create_polygon(10,10,20,20,100,50,20,100, fill='', outline='green', width=2)
fenetre.mainloop()
Translater un polygone
Testez et étudiez l'exemple ci-dessous.
import tkinter
def translate() :
""" On translate chaque sommet du polygone1 par la translation de vecteur u( xu, yu )."""
global xa,ya,xb,yb,xc,yc
xu = ux.get() # on récupère la valeur donnée au curseur ux
yu = uy.get() # on récupère la valeur donnée au curseur uy
xa, ya = xa+xu, ya+yu # nouvelles coordonnées du sommet A
xb, yb = xb+xu, yb+yu # nouvelles coordonnées du sommet B
xc, yc = xc+xu, yc+yu # nouvelles coordonnées du sommet C
# on rédéfinit polygone1 :
canevas.coords(polygone1, xa, ya, xb, yb, xc, yc)
fenetre = tkinter.Tk()
# définition d'une zone de dessin dans la fenêtre tkinter :
largeur = 500
hauteur = 500
canevas = tkinter.Canvas(fenetre, width = largeur, height = hauteur)
canevas.pack()
# définition d'un triangle de sommets A(xa,ya), B(xb,yb), C(xc,yc) :
xa, ya = 0, 0
xb, yb = 10, 10
xc, yc = 0, 20
polygone1 = canevas.create_polygon(xa,ya, xb,yb,xc,yc, fill='red')
# on définit un curseur pour que l'utilisateur puisse indiquer
# l'abscisse du vecteur de translation :
ux = tkinter.DoubleVar()
scale = tkinter.Scale(fenetre, variable = ux,from_ = -20, to = 20,resolution = 0.5)
# on affiche le curseur sur la gauche de la fenêtre :
scale.pack(side = 'left')
# on définit un curseur pour que l'utilisateur puisse indiquer
# l'ordonnée du vecteur de translation :
uy = tkinter.DoubleVar()
scale = tkinter.Scale(fenetre, variable = uy, from_ = -20, to = 20, resolution = 0.5)
# on affiche le curseur sur la droite de la fenêtre :
scale.pack(side = 'right')
# définition d'un bouton à cliquer ayant pour effet une translation du triangle
# translation définie par les curseurs
bouton = tkinter.Button(fenetre, text = "translatez le triangle", command = translate )
bouton.pack()
fenetre.mainloop()
Translation 'animée'
Testez et étudiez l'exemple ci-dessous.
import time
import tkinter
# fenêtre tkinter
# dans laquelle on peut placer canevas, boutons...
fenetre = tkinter.Tk()
# ouverture d'un canevas sur fond blanc
canevas = tkinter.Canvas(fenetre, width = 500, height = 500)
canevas.configure(bg = "white")
canevas.pack()
# création de deux triangles
triangle1 = canevas.create_polygon(5,5,20,20,5,15, fill = 'orange')
triangle2 = canevas.create_polygon(400,400, 420,420, 400, 420, fill = 'brown')
# déplacements successifs :
for i in range(60) :
# translation de 5px en abscisse et 5px en ordonnée du triangle 1 :
canevas.move(triangle1, 5,5)
# translation de -5px en abscisse et -5px en ordonnée du triangle 2 :
canevas.move(triangle2, -5,-5)
# rafraîchissement de la fenêtre (indispensable, sinon le tracé
# n'est fait qu'en fin de boucle et on ne verra que la position finale)
fenetre.update()
#léger temps d'attente pour voir le mouvement
time.sleep(0.05)
fenetre.mainloop()
Plutôt que time.sleep
,
il est préférable d'utiliser after
du module tkinter, ce qui donne :
import tkinter
# fenêtre tkinter
# dans laquelle on peut placer canevas, boutons...
fenetre = tkinter.Tk()
# ouverture d'un canevas sur fond blanc
canevas = tkinter.Canvas(fenetre, width = 500, height = 500)
canevas.configure(bg = "white")
canevas.pack()
# création de deux triangles
triangle1 = canevas.create_polygon(5,5,20,20,5,15, fill = 'orange')
triangle2 = canevas.create_polygon(400,400, 420,420, 400, 420, fill = 'brown')
# déplacements successifs :
for i in range(60) :
# translation de 5px en abscisse et 5px en ordonnée du triangle 1 :
canevas.move(triangle1, 5,5)
# translation de -5px en abscisse et -5px en ordonnée du triangle 2 :
canevas.move(triangle2, -5,-5)
# rafraîchissement de la fenêtre tous les 5 centièmes de secondes :
fenetre.after(50,fenetre.update())
fenetre.mainloop()
Vous pouvez maintenant
pratiquer un peu.