Maîtriser le Canvas Tkinter : Dessin, Manipulation et Exportation
La création d'une surface de dessin avec Tkinter passe par l'utilisation du constructeur Canvas. Cette classe permet de définir les dimensions de la zone de dessin grâce aux arguments nommés width et height. Il est également possible de spécifier une couleur de fond via l'argument bg (background).
Les coordonnées sur un Canvas Tkinter sont exprimées en pixels, où le premier pixel est numéroté 0, le suivant 1, et ainsi de suite. Bien que pour les débutants, la plupart de ces options puissent être ignorées, il est parfois nécessaire de les modifier pour obtenir le comportement souhaité.
Parmi ces options, on retrouve le highlightthickness, qui définit l'épaisseur de la bande d'activation du focus, souvent représentée en vert. La couleur du bord du Canvas peut être définie avec l'argument bg, par exemple bg="ivory".
Les positions spécifiées lors de la création d'objets tels que des rectangles sont interprétées au sens large. Par exemple, un rectangle dont la largeur commence au pixel 10 et se termine au pixel 100 inclut le pixel 100.
Exportation et Sauvegarde d'Éléments du Canvas
Pour sauvegarder le contenu d'un Canvas dans un format d'image comme PNG, la méthode postscript du Canvas est indispensable. Cette méthode permet d'exporter le contenu au format EPS (Encapsulated PostScript).
Il est possible de capturer des éléments graphiques tels que des rectangles ou du texte directement depuis Tkinter.
Dessin de Formes Géométriques
Rectangles
Un rectangle peut être dessiné avec l'argument nommé fill, qui accepte un nom de couleur pour le remplissage. Par défaut, les rectangles sont délimités par une bordure noire d'un pixel d'épaisseur. Pour supprimer cette bordure, on utilise l'argument outline=''.
La dimension d'un rectangle, lorsqu'une bordure est présente, est calculée comme la différence entre les abscisses des côtés parallèles, plus un pixel si le bord est inclus. Lorsque le bord est retiré, les dimensions se calculent simplement par la différence entre les abscisses et les ordonnées correspondantes.
Il est possible de définir les coordonnées d'un rectangle en spécifiant les coordonnées du coin supérieur gauche (x0, y0) et du coin inférieur droit (x1, y1). La coordonnée finale (x1, y1) représente le pixel juste extérieur à la boîte. Par exemple, (0,0,10,5) crée un rectangle s'arrêtant au pixel (9,4). La bordure peut être interne et externe simultanément.
Pour faciliter la définition des rectangles, une fonction peut être créée pour accepter le point haut-gauche, la largeur et la hauteur comme paramètres, en gérant la taille du rectangle en intégrant la bordure.

Cercles et Ellipses
Contrairement à ce que l'on pourrait attendre, un cercle n'est pas construit en spécifiant son centre et son rayon. La construction d'un cercle ou d'une ellipse repose sur le rectangle qui les contient. L'espacement vertical et horizontal entre deux points doit être égal pour former un cercle, cet espacement représentant le diamètre.
Un cercle possède par défaut un bord noir d'une épaisseur de 1 pixel. Si l'option width est définie à 0, le cercle n'a plus de bord visible. Si width est mis à 2, un pixel est ajouté à l'intérieur et un pixel sur les droites.
Pour dessiner un cercle centré au point (100, 100) avec un rayon de 5 pixels, les bords du cercle se situent sur les droites d'équations x=xC+R et x=xC-R.
Il est possible de créer des arcs de cercle ou d'ellipse en spécifiant les angles de début et d'étendue. Par défaut, l'angle de rotation est de 0°. L'angle d'étendue, défini par le paramètre extent, est exprimé en degrés. Par défaut, extent=90 crée un quart de cercle.

Polygones
Par défaut, les polygones sont remplis en noir et sans bordure (fill="black" et outline=''). Pour créer des polygones, il faut généralement spécifier les coordonnées des sommets à la main. L'ajout du paramètre smooth=1 lors de l'appel à create_polygon permet d'adoucir les courbes.
Il est possible de tracer des formes plus complexes comme des triangles, des hexagones, et même des figures comme Pac-Man en utilisant les méthodes de création de polygones et d'arcs.
Texte et Images sur le Canvas
Texte
Le placement de texte sur un Canvas se fait via l'argument text, qui contient la chaîne de caractères à afficher. L'option anchor permet de spécifier le point cardinal (Nord, Sud, Est, Ouest, etc.) par rapport auquel le point de référence du texte est positionné.
Images
Le Canvas supporte le placement d'images stockées sur le disque. Le format JPEG n'est généralement pas pris en charge directement. Avant d'utiliser une image, il faut la convertir dans un format propre à Tkinter en utilisant la classe PhotoImage, en lui fournissant le chemin du fichier image.
Une fois l'image convertie, elle peut être incorporée dans le Canvas via la méthode create_image. Il est crucial de noter que les arguments de dimensions pour create_image n'ont pas la même signification que pour d'autres éléments comme create_rectangle.
Une préoccupation fréquente concerne la visibilité des images. Si une variable contenant une image est locale à une fonction et est ensuite éliminée par le garbage collector de Python, l'image peut devenir invisible. Pour éviter cela, il faut s'assurer que la référence à l'image soit maintenue, par exemple en la stockant dans une variable globale ou un attribut d'instance.

Manipulation des Éléments du Canvas
Identification et Gestion des Items
Chaque objet placé sur un Canvas Tkinter, qu'il s'agisse d'un rectangle, d'une ligne ou d'une image, est créé via une méthode commençant par create_ et reçoit un identifiant unique (ID), qui est un entier strictement positif. Ces IDs sont récupérables lors de la création de l'élément et sont utiles pour les manipulations ultérieures.
Il est possible de récupérer toutes les IDs des objets présents sur un Canvas. Les identifiants générés sont uniques, même après la suppression d'items. Cela signifie qu'une fois qu'un ID est attribué, il ne sera pas réutilisé.
Suppression d'Éléments
Le Canvas offre une méthode delete pour supprimer des éléments. Pour effacer tous les items présents, on utilise l'appel Canvas.delete('all'). Il est également possible de supprimer des éléments spécifiques en utilisant leur ID.
La suppression d'un item ne se limite pas à sa disparition visuelle ; il est retiré de la mémoire du Canvas. Cela est important, par exemple, pour des objets en mouvement qui sortent de la zone visible mais qui continuent d'être référencés.
Modification des Propriétés des Éléments
Il est possible de modifier les propriétés d'un item existant, comme sa couleur de remplissage ou ses dimensions, sans avoir à le recréer entièrement. La méthode itemconfigure permet d'accéder à ces options, mais elle ne permet pas de modifier la position de l'item sur le Canvas.
Pour faire disparaître temporairement un item et le faire réapparaître sans le détruire ni le reconstruire, on peut utiliser l'option state. En la réglant sur 'hidden', l'item devient invisible. Pour le réafficher, on la remet à 'normal'.
Déplacement des Éléments
La méthode move permet de déplacer un objet sur le Canvas. Ce déplacement est une translation définie par un vecteur. Pour déplacer un item du point A(xA, yA) vers le point B(xB, yB), le vecteur de translation est (xB-xA, yB-yA).
La méthode move attend trois arguments : l'ID de l'item à déplacer, le déplacement selon l'axe X, et le déplacement selon l'axe Y. Il est également possible de spécifier la position finale des sommets d'un objet pour le déplacer.

Détection et Gestion des Collisions
Détection de Chevauchement
La méthode find_overlapping permet de détecter si des items se touchent. Elle retourne une liste des IDs des items qui se chevauchent avec une zone spécifiée.
Recherche de l'Item le Plus Proche
Le Canvas dispose d'une méthode pour connaître l'ID de l'item le plus proche d'un point donné, appelée find_closest. Cette fonctionnalité est utile, par exemple, pour identifier l'objet sur lequel l'utilisateur a cliqué.

Organisation et Hiérarchie des Éléments
Ordre de Superposition (Z-order)
Lorsque de nouveaux éléments sont créés sur un Canvas, ils sont placés par défaut au-dessus des éléments existants. La méthode tag_raise permet de placer un élément spécifié au-dessus des autres. Inversement, tag_lower permet de le placer en dessous.
Chaque item créé peut recevoir un ou plusieurs tags (identifiants textuels) sous forme de chaînes de caractères. Ces tags permettent de grouper des éléments et de les manipuler collectivement, par exemple pour les déplacer ou les modifier.
COURS COMPLET JAVASCRIPT [60/65] - Rotations et translations dans le canvas
Zones de Défilement et Barres de Défilement
Définition de la Zone Utile
L'option scrollregion permet de définir une zone de défilement paramétrable, modifiant ainsi l'origine des axes du Canvas. Par exemple, avec scrollregion=(-200, -200, 200, 200), l'origine (0,0) se retrouve au centre de cette région.
Utilisation des Barres de Défilement
Les barres de défilement (horizontales et verticales) permettent de rendre accessible une zone de dessin qui dépasse la taille visible du Canvas. Le widget Scrollbar est utilisé pour créer ces barres, qui sont ensuite liées au Canvas pour gérer la vue de la zone utile.
La relation entre la zone de vue et la zone utile est gérée par des ratios internes au widget Scrollbar. La taille du curseur de défilement sur la barre est proportionnelle à la taille de la zone de vue par rapport à la zone utile.

Principes de Base et Bonnes Pratiques
La création d'une boucle infinie, souvent appelée "boucle de jeu" dans le contexte des jeux, est un grand classique dans la conception d'applications Tkinter qui nécessitent des mises à jour continues, comme les animations. L'instruction time.sleep() peut être utilisée pour temporiser l'exécution et éviter une surcharge du processeur.
Lors du dessin d'éléments, il est important de considérer le décalage d'origine potentiel du Canvas ou de supprimer la marge par défaut lors de sa création pour éviter des dessins involontaires dans la bordure externe.
L'utilisation de fonctions permet d'organiser le code et de réutiliser des blocs logiques. Il est également recommandé de gérer les variables locales et globales avec soin, en privilégiant l'utilisation d'attributs d'instance (self.variable) au sein des classes pour une meilleure encapsulation.
tags: #effacer #texte #canvas #tkinter
