Widget Canvas

Widget Canvas

Syntaxe pour créer une zone graphique de type Canvas : nom_zoneDessin = tk.Canvas(cible [, options]).

Une zone de dessin peut contenir des objets variés (liste non exhaustive) :

  • une ligne : nom_zoneDessin.create_line(x1, y1, x2, y2) ;
  • un rectangle : nom_zoneDessin.create_rectangle(x1, y1, x2, y2) ;
  • une ellipse : nom_zoneDessin.create_oval(x1, y1, x2, y2) ;
  • un polygone : nom_zoneDessin.create_polygon(...) ;
  • du texte : nom_zoneDessin.create_text(x, y, text=chaîne) ;
  • une image : nom_zoneDessin.create_image().

Les coordonnées (x1, y1) et (x2, y2) sont celles des points M1 et M2 d'une diagonale du rectangle dans lequel la forme est inscrite.
Attention, le zéro est positionné en haut à gauche de la zone de dessin (O,x) est vers la droite et (O,y) vers le bas.

Ces objets possèdents des attributs communs : width = épaisseur du contour, fill = couleur de remplissage, outline = couleur de contour, activefill = couleur de remplissage au survol de la souris, state = 'normal' (ou '!disabled'), 'disabled', 'hidden' (un objet peut être caché, désactivé).

Une fois créés, il est possible de déplacer, modifier, supprimer les objets.
Méthodes utilisables avec les objets graphiques (liste non exhaustive) :

  • nom_zoneDessin.coords(nom_objet, x, y) (déplacement absolu : nouvelles coordonnées);
  • nom_zoneDessin.move(nom_objet, dx, dy) (déplacement relatif de dx, dy à partir de la position initiale);
  • nom_zoneDessin.delete(nom_objet) (suppression d'un ou plusieurs objets);
  • nom_zoneDessin.itemconfig(nom_objet, attribut=valeur) (modification d’une ou plusieurs propriétés);
  • nom_zoneDessin.findclosest(x, y) (recherche l'objet le plus proche au voisinage de la position (x, y) et retourne un numéro qui correspond à un objet qu'on peut alors supprimer, modifier… ).

La méthode coords permet également de déterminer les coordonnées d'un objet donné : nom_zoneDessin.coords(nom_objet) renvoie les coordonnées de nom_objet.

Voir Gestion des objets pour atteindre un ojet spécifique via son "id" (les objets sont automatiquement numérotés dans l'ordre de leur création, l'id est ce numéro) ou via un "tag" (il est possible d'affecter des étiquettes ou tags aux objets, ce qui permet d'identifier un ensemble d'objets ayant tous le même tag ou un objet particulier ayant un tag unique).

Tables étape 6

On souhaite afficher le score sous forme d'un "bar graph" (points de vie) : le score ne peut être que positif ou nul (pas de points négatifs) mais il peut augmenter ou diminuer en fonction des réponses.

  1. Créer une variable score et l'initialiser.
  2. Créer une variable hCanvas (hauteur du canvas) et l'initialiser à 100.
  3. Ajouter un widget canvas de hauteur hCanvas, de largeur 20, aligné à gauche.
  4. Modifier la fonction afficheResultat() de façon à ce qu'elle mette à jour le score et qu'elle trace un rectangle vert à la position convenable dans le canvas en cas de bonne réponse, un rectangle blanc à la place du dernier rectangle vert dans le cas contraire.
  5. Bug : en cliquant plusieurs fois sur le bouton vérification, le score augmente... Remédier à ce problème, par exemple en désactivant/réactivant les boutons (méthode config(state='disabled') et config(state='normal') des boutons).
  6. Ajuster la hauteur du canvas en fonction du nombre de questions et empêcher de dépasser ce nombre.

Précédent

  1. Modifier le script fourni et ajouter un bouton commandant un déplacement aléatoire du chat (ou d'un autre objet) dans la zone de dessin.
    Exercice canvas a
    Outils : coords(), from random import randint, randint(a,b).
  2. Créer l'interface suivante permettant de supprimer un objet au voisinage d'un point dont on entre les coordonnées x et y.
    Exercice canvas b
    Outils : get(), findclosest(), delete().

Faire bouger le chat


Supprimer les objets


Code


Lien de téléchargement de l'image du chat pour tester le script : Scratch Scratch

Commentaires

Dans cet exemple, les 5 objets créés (rectangle, cercle, ligne, texte et image) sont tous placés dans l'objet/variable nommé "dessin" de type canvas (en POO, on dit que "dessin" est une instance de la classe Canvas).
L'objet "dessin" est lui-même placé dans la fenêtre "jeu" ("jeu" est une instance de la classe Tk).
Par défaut, les coordonnées x et y indiquées dans nom_zoneDessin.create_image(x, y, image=nom_image) sont les coordonnées du centre de l'image.

Attention, pour utiliser une image, il existe deux façons de procéder :

  1. Utiliser un chemin complet de la forme tk.PhotoImage(file='E:\\mon_dossier\\mon_image.png') ;
  2. Placer l'image dans le même dossier que le script python (celui-ci doit donc y être sauvegardé) et cliquer sur le coin inférieur droit du bouton de l'étoile des favoris dans l'explorateur de fichiers de pyzo et choisir "Aller dans ce dossier (shell courant)". Cf. copie d'écran ci-dessous.
Fenêtre - Widgets

Attention, avec pyzo, en cas de message d'erreur se terminant par : _tkinter.TclError: couldn't open "Scratchcat2.png": no such file or directory. Il faut corriger l'erreur puis redémarrer le shell avant de relancer une exécution.

Pour déterminer le chemin jusqu’à un fichier, afficher l’arborescence dans Pyzo (menu Outils/File browser), faire un clic droit sur le fichier, copier/coller le chemin puis remplacer \ par \\.

Utiliser des ressources web - Fichiers

Canvas (tkinter-docs)
Canvas - TkDocs

Attention au format des images (cette image fonctionne), utiliser paint si nécessaire pour convertir une image récalcitrante au format png.