Table des matières
1. notion d'application graphique 8
1.1. les origines ..8 1.2. les principes .8
1.3. programmation ..9
1.4. le cas de Python 9
1.5. l'interfaçage de tkinter .9
2. la librairie dans l'arborescence Python .10
3. la documentation 12
4. une documentation illustrée, en français .13
4.1. notre objectif .13
4.2. en français .13
5. première approche .14
5.1. étape 1 .14 5.2. étape 2 .15
5.3 étape 3 ..16
6. les widgets de tkinter 18
6.1. liste des widgets .18
6.2. les fonctions des widgets 18
6.3. les constructeurs 19 6.4. le problème du nom d'une instance ..19
1. couleurs ..20
1.1. couleurs nommées 20
1.2. couleur codées hex ..20
1.3. méthodes de widget .20
2. bordures .21
2.1. six reliefs .21
2.2. codage .21
3. unités 21
4. l'attribut bitmap 22
5. l'attribut cursor .22
6. justification des textes ..23
7. complément sur les types de données .23 tk02 : BitmapImage et PhotoImage .24
1. questions de formats .24
1.1. l'attribut image .24
1.2. modes d'une image bitmap 24
1.3. question de fichier .24
1.4. un exemple 25
2. la classe BitmapImage .26
3.1. syntaxe 26
3.2. les options .26
3.3. les méthodes 26
3. la classe PhotoImage 26
3.1. syntaxe 26
3.2. les options .26
3.3. les méthodes 27
4. Un problème avec l'attribut «image» 27
4.1. on considère le script suivant : 27 4.2. traiter le bug ..28
1. descripteur de fonte ..30
1.1. caractéristiques d'une fonte ..30
1.2. valeur de fonte : les descripteurs de fonte .30
1.3. familles prédéfinies 31
2. Le module Font 31
2.1. le constructeur Font ..31 2.2. les options de Font ..31
2.3. les méthodes d'instance de Font 31 2.4. fonctions du module font .32
1. géométrie des fenêtres 34
1.1. geometry .34
1.2. fixer la géométrie d'une fenêtre ..34
1.3. retrouver la géométrie d'une fenêtre .34
2. Les gestionnaires de placement .35
2.1. les trois gestionnaires ..35
2.2. règles d'usage .35
3. Le gestionnaire Pack 35
3.1. fonctionnement du gestionnaire Pack ..35
3.2. les méthodes de widget ..37 3.3. les valeurs d'attribut : 38
3.4. les options .38
4. le gestionnaire Grid 38
4.1. principe du gestionnaire Grid 38
4.2. les méthodes de Grid ..39
4.3. les options de configuration de grille 39
4.4. les options de cellule 39
5. Le gestionnaire Place ..40
5.1. principe du gestionnaire Place .40
5.2. les méthode du gestionnaire Place 40
5.3. le valeurs d'options 40
5.4. les options .40
6. la troisième dimension .41
6.1. empilement des «calques» 41 6.2. Les méthodes ..41
1. méthodes d'attributs ..42
1.1. attributs donnés à un widget .42
1.2.modification d'un ou plusieurs attributs .42
1.3. accès aux attributs .42
2. attributs système .43
3. attributs de bordure et de marge .44
4. attributs de couleur 44
5. attributs pour les gestionnaires de géométrie (rappel) .44
6. les attributs default et state 45
7. l'attribut command ..45
8. attributs de désaffection (disable) ..45 tk06: les méthodes partagées .46
1. méthodes portant sur les attributs ..46
1.1. méthodes de configuration 46
1.2. méthodes d'options de classes 46
2. méthodes concernant les événements 47 3. méthodes de presse-papier ..47
4. méthodes relatives aux placements ..47
4.1. gestionnaires de placement ..47
4.2. empilement des widgets .47
5. mesures relatives au widget .48
6. méthodes portant sur la console .48
7. méthodes de souris ..49
8. les boucles .49
9. méthodes de gestion du déroulement de programme ..51
10. méthodes d'identification ..52
11. méthodes de focus ..53
1. les événements reconnus ..56
1.1. événements clavier 56
1.2. événements souris 56
1.3. événements fenêtre ..56
2. la notion de séquence ..57
2.1. écrire une séquence .57
2.2. exemples : .57
2.3. événements virtuels ..58
2.4. le cas de la molette 58
3. gestionnaire d'événement ..58
3.1. fonction gestionnaire 58
3.2. l'objet Event ..59
3.3. cas mixtes ..60
4. la liaison ..60
4.1. les bindtags ..60
4.2. les niveaux de liaison ..60
4.3. le retour de bind() ..63
4.4. méthodes de suppression de liaisons ..63
4.5. génération d'événement : event_generate() 63
5. Les protocoles .64
5.1. les trois modes de liaison ..64 5.2. la syntaxe ..64 pour s'y retrouver dans la gestion des événements 64 annexe : les keysym ..65 clavier de base .65 pavé numérique ..66
1. les constructeurs .68
2. les attributs 68
2.1. liste des attributs 68
2.2. les attributs spécifiques ..68
3. les méthodes spécifiques 69
3.1. relations avec le gestionnaire de fenêtres .69 3.2. Icone et visibilité .69
3.3. Style .70
3.4. géométrie et position 70
1. le constructeur .73
2. les attributs 73
2.1. liste des attributs 73
2.2. les attributs spécifiques ..73
3. un exemple de barres de menu ..74
5. exemple de menu popup 75
6. les méthodes spécifiques 76
6.1. les options d'items .76
6.2. les méthodes d'ajouts d'items à un menu ..77
6.3. méthodes de configuration 78
6.4. méthodes de popup ..78 6.5. Divers ..78
1. le constructeur .79
2. options .79
2.1. liste des options de Frame .79
2.2. liste des options de LabelFrame .79
2.3. attributs spécifiques ..80
3. méthodes ..80 tk11 : PanedWindow ..81
1. le constructeur .81
2. options .82
2.1. liste des options de PanedWindows .82
2.2. options spécifiques : .82
3. configuration de panneaux 83
2. options .86
2.1. liste des options ..86
2.2. attributs spécifiques ..86
3. la fonction commmand .87
3.1. cas où le curseur de la barre de scroll est déplacée .87
3.2. cas où un mouvement unitaire est requis .87
4. méthodes 87
5. un script pour montrer le fonctionnement des connexions .88
5.1. la double connexion ..88
5.2. le script commenté 89
1. le constructeur .92
2. les attributs 92
2.1. liste des attributs 92
2.2. les attributs spécifiques ..92
1. le constructeur .94
2. les attributs 94
2.1. liste des attributs .94
2.2. attributs spécifiques ..94
2. méthodes ..95 tk15 : Checkbutton .96
1. le constructeur .96
2. les attributs 96
2.1. liste des attributs .96
2.2. attributs spécifiques ..96
3. méthodes ..97 tk16 : Radiobutton ..98
1. le constructeur .98
2. les attributs 98
2.1. liste des attributs .98
2.2. attributs spécifiques ..98
3. méthodes 100 tk17 : Listbox ..101
1. le constructeur ..101
2. les attributs .101
2.1. liste des attributs .101
2.2. les attributs spécifiques 101
3. les méthodes spécifiques .102
1. le constructeur ..106
2. les attributs .106
2.1. liste des attributs ..106
2.2. les attributs spécifiques 106
3. un exemple de widget OptionMenu .107
4. les méthodes .109 tk19 : Entry 110
1. le constructeur 110
2. les attributs ..110
2.1. liste des attributs ..110
2.2. les attributs spécifiques .110
3. les méthodes ..112 4. scroller le widget Entry ..114
1. le constructeur ..117
2. les attributs ..117
2.1. liste des attributs ..117
2.2. les attributs spécifiques .117
3. se repérer dans un texte ..119
3.1. les index de position ..119
3.2. les marqueurs 120
4. les balises (tags) ..120
4.2. la pile des tags ..121
4.3. les option de tag ..121
5. les méthodes .121
5.1. utilitataires ..121
5.2. méthodes générales d'édition 122
5.3. méthodes pour les marqueurs ..122
5.4. méthodes pour les éléments fenêtrés inclus ..123
5.5. méthodes pour les images incluses 123
5.6. méthodes pour les balises ..124
5.7. méthode de rendu ..124
5.8. méthodes de recherche 125
5.9. méthodes pour les ascenseurs .125
6. quelques exemples .126
6.1. méthodes de sélection ..126
6.2. un exemple simple ..126
1. le constructeur ..130
2. les attributs .130
2.1. liste des attributs ..130
2.2. les attributs spécifiques 130
3. fonctionnement du widget 131
3.1. dimensions .131
3.2. les coordonnées ..132
3.3. identification et taguage des items .134
4. méthodes générales du widget Canvas 135
4.1. méthodes générales ..135
4.2. méthodes de manipulation de tags .135
4.3. méthodes relatives aux dimensions et aux transformations ..136
4.4. méthodes relatives aux événements .136
4.5. méthodes de texte ..136
4.5. méthodes de recherche d'item ..137
4.6. méthodes de scroll .137
5. les méthodes create 138
5.1. création à partir d'un Bitmap ou d'une Image 138
5.2. création de ligne et polygone .139 5.3. création de rectangle, d'ellipse .141
5.4. création d'un arc ..141 5.5. création de texte ..141 5.6. création de fenêtre ..142
1. le constructeur ..143
2. les attributs .144
2.1. liste des attributs ..144
2.2. les attributs spécifiques 144
1. le constructeur ..147
2. les options 148
2.1. la liste des options ..148
2.2. les options spécifiques .148
3. les méthodes du widget Spinbox .150
(voir )
version : tout le travail a été réalisé avec Python3.2. sous Linux (et vérifié sous Windows) et la version (8.5) de tkinter qui l'accompagne.
Une application graphique est une application qui est exécutée dans une unité d'interface graphique
(GUI, pour Graphic User Interface). Les GUI les plus connus sur le PC sont Windows (système Microsoft) et X11 (système Linux). Le premier matériel qui a disposé d'un GUI sur ordinateur personnel a été Lisa (1982), d'Apple, ancêtre du Macintosh, et qui a été repris sur les plates formes Next (qui ont engendré l'actuel Mac OS X d'Apple en 2001). Les principes de l'élaboration d'interface graphique et des logiciels graphiques ont été définis entre 1970 et 1981 au Palo Alto Research Center.
L'interface graphique utilise la métaphore du bureau : des pages empilées ou se chevauchant ; des piles de documents (pages) distribuées sur un bureau ; le dessus d'une des piles est la page active, page sur laquelle on travaille ; les pages peuvent être réunies en dossier ou en systèmes à onglets (notebook) ; des systèmes de classement par listes, répertoires etc. Ce type de métaphore qui paraît si naturelle aujourd'hui n'est cependant pas si évident qu'il y paraît. Les tablettes filent une autre métaphore, plus proche de celle de livres issus d'une bibliothèque : on tourne les pages, on glisse d'une partie du document à une autre, on choisit son application dans une bibliothèque d'applications indépendantes
* Un logiciel graphique se présente sous forme de composants graphiques fenêtrés, et il dispose d'un outil de pointage (la souris) qui permet assez souvent de ne pas utiliser la commande par le clavier.
* Par ailleurs, la gestion du logiciel se fait par événements, et non selon un déroulement séquentiel impératif comme dans les logiciels classiques.
les composants fenêtrés
* es éléments fenêtrés affichés sont hiérarchisés et forment un arbre ; à la racine, on trouve la fenêtre principale (root window). Les divers éléments entretiennent un rapport de dépendance du type maître (master) à enfant (child). La dépendance se traduit graphiquement par l'inclusion de l'enfant dans sont maître, sauf pour les fenêtres de haut niveau. Attention, ce rapport de dépendance ne doit pas être confondu, malgré la proximité de vocabulaire avec la hiérarchie des objets (rapport hiérarchique qu'il vaut mieux exprimer en français par les mots ascendant et descendant). Ce rapport de dépendance est identifiable à un rapports de contenant à contenu sauf pour les éléments de haut niveau (les fenêtres Toplevel) : tout élément fenêtré a un conteneur unique, Si le maître est modifié ou s'il disparaît, toute sa progéniture est modifiée (ou disparaît).Supprimer la fenêtre principale revient à supprimer la présence à l'écran du logiciel, et en pratique sa fin.
* La gestion est événementielle : cela implique qu'un dispositif de surveillance scrute en permanence toutes les sources d'événements possibles : frappe d'une touche au clavier, action d'un timer, actions liées à la souris, au programme, à des éléments d'interface (comme la modification d'une dimension de fenêtre) L'élément racine dispose d'une boucle qui surveille tout ce qui relève de l'application.
Sortir de cette boucle s'accompagne immédiatement de la suppression de la réactivité aux événements. Dans les logiciels de «console», il existe au mieux un élément qui est en attente d'un événement (en général, la frappe dite de «validation» venant du clavier). Dans les logiciels graphique, ce sont tous les éléments qui peuvent être en «en attente» d'un événement.
La notion d'interface graphique fenêtrée et celle de programmation objet naissent en même temps. Comme ce mode de modélisation se prête bien à la programmation de l'interface graphique, l'essentiel des langages de la programmation graphique relève de la POO. Pour mémoire, Smalltalk, C++, Delphi (Pascal), Visual Basic, Java. Les systèmes qui implémentent l'interface graphique fenêtrée comportent deux parties, le système d'exploitation proprement dit, et une surcouche graphique capable de commander la carte graphique. C'est cette surcouche, Windows (Microsoft), X11 (système Linux) que le programme commande. Depuis les années 1990, on voit apparaître des modules complémentaires (frameworks) que l'on peut interfacer aussi bien avec les langages compilés que les langages interprétés et indépendants des langages destination
1.4. le cas de Python.
Python comporte plusieurs version : CPython, le Python classique, Jython, écrit en Java, IronPython etc. Jython qui fonctionne sous Java peut utiliser les capacités graphiques de Java (awt, swing).
L'activité foisonnante des programmeurs Python a permis de proposer au moins quatre bibliothèques graphiques d'origine externe, dont voici une évocation rapide :
librairie | wrapper | commentaire | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
tk | tkinter | Écrit en Tcl. Comporte tous les essentiels. Inclus le système Python. Utilisé aussi par Perl, Ruby. Existe en version Python 3. Exploite peu le système hôte. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
wxWidget | wxPython | Bibliothèque plus riche que tkinter. Exploite au maximum le système hôte (Windows, Linux ). Les applications on le look du système hôte. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Qt | PyQt, Pyside | Développé en C++. À la base de KDE sous Linux. C'est la cour de grands ! Programmation assez spécifique. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Gtk | PyGtk | Comparable à tk ou wxWidget. Peut être programmé avec le logiciel Glade (dont il existe une version pour wxPython). 1.5. l'interfaçage de tkinter. Pour aider à comprendre comment se situe la librairie tkinter dans le complexe logiciel, on propose le schéma qui suit. Parmi les choses importantes, il faut signaler la structure tripartite de tkinter : - le cœur de tkinter comprend l'essentiel des routines ; ces routines ont un fonctionnement très classique puisque une fois appelées, elles effectuent leur tâche jusqu'au bout avant de rendre la main. - le superviseur des événements : cette partie comporte une surveillance des événements, et les empile. Le traitement des événements est donc différé et certains événements sont simplement oubliés. Il faut penser aussi que dans les système à un seul thread, si une boucle logicielle est engagée, le système de surveillance est interrompu. Au cours d'un dessin d'animation dans un canevas, pas question d'activer un bouton ; on y parvient cependant en multithread pour lequel Python est bien équipé. le gestionnaire de fenêtre est chargé du calcul des éléments d'affichage et de la commande de l'interface graphique du système. Ce gestionnaire fonctionne sur le mode paresseux (idle). Il n'effectue les calculs demandés que lorsqu'il n'y a rien de plus urgent à faire. Le cas d'espèce consiste à demander à ce gestionnaire d'effectuer une tâche complexe, utilisant d'autres éléments graphiques déjà programmé. Pour que cela fonctionne, il faut être sûr qu'il n'y a pas de tâches en attente dont on désire exploiter le résultat : par exemple, si on demande à une fenêtre d'être modale sur une fenêtre hôte, il faut être sûr que celle-ci soit calculée complètement -peu importe qu'elle soit effectivement affichée- On peut sinon avoir un comportement partiellement modal ! bonne réaction à l'iconisation, mauvais affichage-. 2. la librairie dans l'arborescence Pythontkinter est un wrapper qui se situe dans la librairie de Python. C'est un module répertoire. La librairie python peut se situer dans une autre arborescence ; cela dépend de l'implémentation de Python dans le système d'exploitation. Le répertoire se présente ainsi :
-rw-r--r-- 1 root root 77690 2011-09-05 23:30 -rw-r--r-- 1 root root 56250 2011-09-05 23:30 -rw-r--r-- 1 root root 14552 2011-09-05 23:30 -rw-r--r-- 1 root root 11488 2011-09-05 23:30 -rw-r--r-- 1 root root 11395 2011-09-05 23:30 -rw-r--r-- 1 root root 6135 2011-09-05 23:30 drwxr-xr-x 2 root root 4096 2012-12-26 17:25 __pycache__ -rw-r--r-- 1 root root 3701 2011-09-05 23:30 -rw-r--r-- 1 root root 2887 2011-09-05 23:30 -rw-r--r-- 1 root root 1814 2011-09-05 23:30 -rw-r--r-- 1 root root 1793 2011-09-05 23:30 -rw-r--r-- 1 root root 1568 2011-09-05 23:30 -rw-r--r-- 1 root root 1493 2011-09-05 23:30 -rw-r--r-- 1 root root 1412 2011-09-05 23:30 -rw-r--r-- 1 root root 148 2011-09-05 23:30 * Le répertoire est un module car il possède le présent fichier. Lors de l'importation du module, le fichier est exécuté, et les classes, fonctions et constantes qu'il définit sont importées. On rappelle qu'il y a deux grandes façons pour importer un module : - from tkinter import <données à importer> - import tkinter Dans le premier cas, les données à importer sont citées sous forme d'un liste de noms séparés par des virgules : from tkinter import Tk, Toplevel, Label, Button ou si l'on veut tout importer : from tkinter import * Dans ce cas, les données à importer sont utilisée sans préfixe et seules les données importées sont connues du script d'importation : monBouton = Button(monParent, text="QUITTER") fenetrePrincipale = Tk() monBouton = tkinter.Button(monParent, text="QUITTER") fenetrePrincipale = () Attention : si on fait from tkinter import *, on ne connaît que les éléments de __init__, pas ceux des fichiers du répertoire. On peut cependant importer un module inclus par les deux méthodes : from tkinter import messagebox from tkinter.messagebox import askyesno import tkinter.messagebox as popMsg import tkinter.messagebox * TixTk Interface eXtension est une extension de tkinter qui offre des composants de plus haut niveau (plus de 40) comme ComboBox,NoteBook (onglets), DirTree,FileSelectBox. Il est en principe inclus dans toutes les éditions de Python. * Redéfinit des composants de tkinter : Button,Checkbutton,Entry,Frame,Label,LabelFrame,Menubutton,PanedWindow,Radiobutton,Scale et Scrollbar en améliorant leur aspects Il en ajoute 6 qui sont : Combobox,Notebook,Progressbar,Separator,Sizegrip etTreeview. Cette librairie n'existe que sur les versions récentes. * Librairie intéressante puisqu'elle permet de disposer d'un composant graphique pour choisir des fichiers. On rappelle que si l'on veut utiliser les éléments de cette librairie (comme les autres du répertoire), il faut les importer explicitement : from tkinter.filedialog import * * Librairie qui fournit des fonctions qui permet la saisie clavier à travers une interface graphique : askinteger, askfloat, askstring * Librairie de drag & drop * Une librairie importante si l'on veut travailler finement sur les fontes (rechercher les fontes disponibles par exemple). Elle complète des dispositions existant dans le cœur de tkinter, et n'est pas utile si on se contente de définir des attributs de fonte pour les composants Label, Button etc. * La librairie la plus communément utilisée pour les petits travaux d'interrogation par popup à travers les fonctions comme askyesno, askokcancel, askquestion * Actuellement non utilisable * Affichage et saisie de texte avec un ascenseur latéral * * Cette librairie est à usage interne : comme elle est importée dans __init__ ses données sont disponibles depuis le module tkinter. * , À usage interne. 3. la documentation. La documentation en français est restreinte. Les tutoriels traitent tous plus ou moins des mêmes sujets et avec un bonheur à relativiser. La documentation de référence n'existe en pratique qu'en anglais. On peut pour des cas d'espèce consulter la documentation Tcl/Tk, partiellement traduite en français () Le passage obligé pour Python est "An Introduction to Tkinter" de Frederik Lundth. Cette documentation date de 1999, et nécessite quelques adaptations ; une mise à jour est annoncée depuis 2006 ! On trouve en la version la plus récente, qui reste incomplète. Cette documentation reste la plus sérieuse malgré de nombreuses inexactitudes et obsolescences. Elle est disponible sur le web aux formats html (version récente) et pdf (vieille version). Il existe une documentation de John W. Shipman pour les étudiants de l'Université du Nouveau Mexique. Elle répond bien à son objet -une référence pour des étudiants-, elle est fiable mais reste lacunaire. S'en tenir à la version originale, en anglais. Bien entendu, il reste la possibilité d'utiliser la documentation interne, engendrée par pydoc3. Le plus simple est de lancer dans une console : pydoc3 -w tkinter pydoc3 -w Pydoc crée alors la doc au format HTML dans le répertoire courant. C'est lourd, assez indigeste, mais précieux pour disposer de références de première main. On peut toujours faire du copier/coller de certaine parties dans Open Office. En veillant toutefois à éviter de trop grosses transpositions qui sont fort longues et hasardeuses. Une doc Python/tkinter est elle aussi disponible dans la doc Python, mais elle s'avère assez peu pratique. 4. une documentation illustrée, en français. 4.1. notre objectifL'objectif est de réaliser un document des références de tkinter, aussi exhaustif que possible, mais pratique pour le programmeur non spécialisé (à l'origine, rédigée pour un atelier de club informatique). Si on compare à une approche telle que celle de Lundh, nous inclurons davantage d'explication, d'exemples, nous évoquerons les pièges ou problèmes rencontrés, quitte a être par ailleurs moins systématique . L'étude d'un composant par exemple pourra comporter plusieurs renvois, alors que la documentation traditionnelle essaie souvent, au prix de nombreuses redites, de constituer un dossier complet pour chaque composant. 4.2. en français L'adaptation française d'une référence pose le problèmes du vocabulaire à employer. Certaines appellations française sont sans problèmes, comme module, importer, variable, fonction, méthode, classe, canevas, option. Ils sont un équivalent du mot anglais, avec lequel ils partagent l'origine linguistique. Mais assez souvent, plutôt qu'un mot aussi général que option, on préfère attribut, qui n'a pas la même connotation de donnée facultative; les options sont en effet des attributs qui peuvent avoir une affectation par défaut, et non des attributs qui peuvent rester indéterminés. Pour le mot font on utilise fonte plutôt que police de caractères. Le mot texte traduisant text désigne une séquence de caractères. Certaines traductions ne devraient pas faire de difficulté : manager devient gestionnaire, event devient événement. Mais un mot comme handler se traduit mal. Ainsi event handler devient plus clairement un gestionnaire d'événement. Même chose pour slider, que nous conservons en l'état. Les méthodes geometry(), pak(), grid(), place() constituent les gestionnaires de géométrie. Les mots command et control sont plus délicats à apparier ; command désignera toujours une fonction. Le mot mark se traduit usuellement par marque. Mais étant donné la polysémie de marque en français, dans le domaine scientifique on préfère marqueur : un marqueur radioactif, la fluorescéine en tant que marqueur. Non utiliserons donc marqueur. Le mot tag est souvent adapté en informatique comme balise ; par exemple en html. C'est une bonne approche, d'autant que le mot étiquette parfois employé est préférable pour la traduction de label. Cependant on peut également garder tag, en précisant. 5. première approche. À travers cet exemple, on va montrer quelle est la structure basique de la programmation d'un logiciel graphique avec tkinter. Cela permettra de fixer le vocabulaire pour la suite du documents. 5.1. étape 1 La première étape consiste à : - importer la librairie tkinter - créer une fenêtre principale - lancer la méthode mainloop.
discussion * la première ligne est un shebang. Un shebang indique dans un environnement UNIX que ce qui suit est un texte interprétable appelé aussi un script. Il précise le mode d'accès à l'interpréteur. Même s'il ne sert pas, il rappelle toujours quel interpréteur doit être utilisé (ici python version 3). On rappelle que l'on peut rendre un script directement exécutable sous UNIX grâce au shebang, en mettant les droits du fichier à «exécutable». Sous Windows, le shebang ne sert pas ; mais on rend exécutable en mettant l’extension du fichier à pyw et en réglant le gestionnaire de fichiers. * L'importation du module permet de disposer de tous les éléments disponibles dans tkinter et de les utiliser sans qualificatif. On peut discuter de ce mode d'importation. Il convient de formuler les remarques suivantes : - si on importe une librairie quelconque après cette première importation, les élémentsnouvellement importés occultent les anciens de même nom. Il n'y a donc pas de problème pour importer ttk sur le même mode, puisque c'est l'effet recherché. - il peut cependant y avoir un hiatus avec une librairie comme pil (traitement d'images), qui contient par exemple un composant Image, homonyme d'un composant de tkinter, et avec des fonctionnalités qui sont différentes. Une règle pratique de conduite est d'importer les librairies externes en utilisant l'importation nominale ou la qualification, et éventuellement un alias : from pil import Image as Img # alias import pil # qualification exécution du script L'exécution du script sous Linux se fait à partir de la console. Note : Dans tout le document, on ne fait pas apparaître la ligne de commande d'exécution ; le nom du fichier exemple apparaît en dernière ligne du script.
5.2. étape 2La seconde étape consiste à doter le logiciel de trois fonctionnalités importantes : - le réglage de la dimension et de la position de la fenêtre - la possibilité de sortir du logiciel autrement qu'un invoquant l'icone de sortie, mais un boutonappartenant à l'interface.
fenPrincipale.mainloop() # # on mettrait ici les actions à exécuter en fin de script # # fichiercommentaires * fenPrincipale.title() On a donné la possibilité de personnaliser le titre * fenPrincipale.geometry ("300x200+150+100") Les fonctions de placement sont désignées sous l'appellation géométrie (geometry) La géométrie d'une fenêtre se décline comme une chaîne : largeur x hauteur + décalage horizontal sur l'écran + décalage vertical sur l'écran Ce gestionnaire de géométrie n'est pas impératif en ce qui concerne les dimensions : si un gestionnaire vient contrecarrer le dimensionnement, il prend le pas sur la définition de géométrie initiale. C'est particulièrement vrai avec les gestionnaires de géométrie pack() et grid(). * def quitter(): Cette fonction est un gestionnaire d'événement c'est-à-dire qu'elle est appelée lorsqu'un événement se produit, ici lorsque le bouton est cliqué. () La fonction est oblige au retour de la méthode bloquante mainloop. * btQuitter = Button(fenPrincipale, text="QUITTER", command=quitter) On ici la création d'un composant graphique fenêtré en occurrence un bouton. Noter le premier argument qui est le maître (master, parent, propriétaire, conteneur). Ce qui suit est la liste des attributs, facultatifs puisque ce sont des paramètres initialisés. Comme le nombre est indéfini, on utilise la notation clef/valeuravec égale. L'attribut command a comme valeur la fonction gestionnaire qui est appelé quand on clique le bouton. * (pady=20) dificultés * Dans un environnement normal (appel en ligne de commande), la fin du script entraîne la destruction de l'application. Mais sur certains environnements (sous Idle par exemple), il faut explicitement détruire l'application. * Dans la pratique, on met souvent un avertissement avant la sortie d'un logiciel, pour éviter les sorties en cas de manœuvre maladroite. Il est logique de placer cet avertissement dans la fonction quitter(). Mais ceci n'évite pas une utilisation intempestive de l'icone de barre de titre. Il est possible de capturer la clic sur cette icône et de l'identifier à l'activation du bouton, ce qui est fait ici ; on peut aussi l'inhiber. 5.3 étape 3La présente étape donne le script minimal pour créer une application tkinter. On peu ensuite broder autour du thème proposé, par exemple utiliser un autre procédé de contrôle.
exécution Les autres widgets de la version 8.5. : Frame, LabelFrame PanedWindow,Scrollbar, Label, Button, Checkbutton, Listbox, Radiobutton,Entry, OptionMenu, Text, Canvas,Scale, Spinbox. Les widgets obsolètes : Message (remplacé par Label) et Menubutton (remplacées par OptionMenu) 6.2. les fonctions des widgets 1. Button chapitre : 14 Le widget est un bouton avec un intitulé. On peut le cliquer par la souris pour activer un gestionnaire d'événement (chapitre 6) 2. Canvas chapitre : 21 Le widget présente un canevas, surface sur laquelle on peut dessiner lignes, textes ou images. 3. Checkbutton chapitre : 15 Il s'agit de la case à cocher classique. Son changement d'état peut activer un gestionnaire d'événement (chapitre 7) 4. Entry chapitre : 19 Le widget Entry permet de saisir une ligne de texte au clavier. Pour cela, il doit avoir le focus. On peut lui adjoindre une base de scroll. 5. Frame chapitre : 10 Le widget Frame est le conteneur universel. 6. Label chapitre : 13 Le widget Label permet de créer un étiquette. Le texte de l'étiquette peut avoir plusieurs lignes. Il peut également afficher un bitmap ou une image. 7. LabelFrame chapitre : 10 Le widget LabelFrame permet de créer un cadre étiqueté sur sa bordure 8. Listbox chapitre : 17 9. Menu : 09 Le widget Menu sert à créer des barres de menu, les menus en cascade associés, les menus popup. 9.OptionMenu chapitre : 18 Le widget OptionMenu est un widget pratique pour créer des menus insérés n'importe où dans le logiciel ; c'est ce que l'on appelle communément un Combobox. 10.PanedWindow chapitre : 11 Le widget permet de gérer les fenêtres à panneaux, où les panneaux sont séparés par de échancrures dont le placement est manipulable par l'utilisateur. 11.Radiobutton chapitre : 16 6.12.Scale chapitre : 22 Le widget Scale permet de disposer un curseur, en vue de la saisie graphique d'une valeur numérique sur une échelle donnée. 6.13.Scrollbar chapitre : 12 Le widget Scrollbar définit un ascenseur, vertical ou horizontal pour certains widget comme frame, entry, canvas etc. 6.14.Spinbox chapitre : 23 Le widget Spinbox comporte une zone de saisie pour un nombre entier sur une échelle donnée et deux petits boutons permettant l'évolution des valeurs de l'échelle, croissant ou décroissant. 6.15.Text chapitre : 20 Le widget Text permet une saisie et un affichage de texte multiligne. Ce widget complexe autorise le formatage de texte, l'insertion d'images, de canevas, la sélection de zones de texte etc. 6.16.Tk chapitre : 08 Ce widget particulier n'a qu'une instance, la fenêtre principale (fenêtre racine /root window). 6.17.Toplevelchapitre : 08 Ce widget définit un fenêtre de haut niveau dans une application ayant déjà sa fenêtre principale. 6.3. les constructeurs Le constructeur de Tk sera abordé dans l'étude de ce composant. Les autres constructeurs sont définis par la méthodes suivante : def __init__(self, master=None, cnf={}, **kw): Ce qui se traduit en pratique par : widget = Constructeur (master=None, options_clef_valeur) * self : l'instance définie * master : le conteneur (maître, conteneur, parent) ; attention :master est aussi un champ du widget, qui a la même valeur que la paramètre passé, sauf s'il n'est pas présent, auquel cas, c'est la fenêtre principale.. * cnf={} : à usage interne ; * **kw : épuise, en nombre indéfini les paramètres d'appel à mot clef, autres que, éventuellement, master et cnf. Si le conteneur n'est pas défini lors de l'appel, le conteneur par défaut est la fenêtre principale. Sauf pour Toplevel, il faut toujours spécifier le conteneur. Le paramètre cnf est à usage interne . 6.4. le problème du nom d'une instance. Chaque instance est nommée automatiquement lors de sa construction. Le nom est un identificateur, c'est-à-dire qu'il est impératif qu'il soit unique dans une application. Il est rare que l'on ait besoin du nom de l'instance en programmation, encore moins de devoir donner un nom autre que celui donné par la machine Python/tkinter. Les règles suivantes sont alors à appliquer : - on peut imposer un nom (chaîne de caractères alpha numériques, avec le souligné) lors dela construction par le paramètre valeur initialisé name="identificateur". - la fenêtre principale est nommée tk ; le constructeur Tk() ne supporte pas le paramètre name. - l'identificateur doit être unique - le nom d'un widget est accessible par la méthode winfo_name() ; il n'existe aucun moyen de changer le nom d'une instance existante. tk01 : valeurs d'attributs standardsLes widgets possèdent des attributs qui portent sur - les couleurs (de fond ou de texte) , - les bordures (largeur, style), - les caractères (fontes, taille, épaisseur, inclinaison) ou - la taille des constituants. Les valeurs de ces attributs ont une structure qui est l'objet de ce chapitre. Pour l'attribut image voir les chapitres sur les classes BitmapImage et PhotoImage 1. couleursLes attributs dont la valeur est une couleur attendent un codage de cette couleur sous forme d'une chaîne de caractères. 1.1. couleurs nomméesCertaines couleurs sont nommées ; il existe 8 valeurs sûres, que l'on retrouve dans toutes les implémentation : "white", "black", "red", "green", "blue", "cyan", "yellow" , "magenta" D'autre couleurs sont reconnues, qui peuvent dépendre des plate-formes : "maroon", "navy", "purple", "grey", "light grey" fenPrincipale.config(bg="purple") On peut écrie aussi bien en majuscules qu'en minuscules ; "RED", "Red", "ReD" sont acceptés. 1.2. couleur codées hex Il y a trois modes possibles pour l'encodage : Le schéma est "#RGB", ou R, G, B sont des chiffres hexadécimaux, correspondant aux composantes rouge, verte et bleue de la couleur dans une représentation RGB. On peut coder une palette de 4096 nuances. La casse n'est pas signifiante. fenPrincipale.config(background="#f8f") # un pourpre * le mode 8 bits par couleur Le schéma est "#RRGGBB", ou R, G, B sont des chiffres hexadécimaux et RR, GG, BB correspondent aux composantes rouge, verte et bleue de la couleur dans une représentation RGB. On peut coder une palette de 16777216 nuances. La casse n'est pas signifiante. btQuitter = Button(fenPr, text="QUITTER", foreground="#FF4040") * le mode 12 bits par couleur (16 bits) Le schéma estidentique. L'encodage est similaire aux précédents, mais les composantes sont sur 3 chiffres (12 bits). Un mode 16 bits est utilisé en interne pour coder les couleurs. 1.3. méthodes de widget* winfo_rgb(nom_couleur) : cette méthode est une méthode de widget ; elle retourne un tuple des valeurs décimales des composantes RGB de nom_couleur. On rappelle qu'en interne, les couleurs sont codées sur 48 bits. exemple : tk01 : valeurs d'attributs standards
* winfo_depth() : retourne le nombre de bits par pixels utilisés dans l'application. 2. borduresTous les composants fenêtrés ont une bordure. La bordure est caractérisée par son épaisseur (borderwidth) et son relief (relief). L'épaisseur relève des mesures (section suivante). 2.1. six reliefsexemple : btQuitter.config(borderwidth=12, relief=RAISED) 2.2. codageUn relief est désigné par une chaîne de caractères, mais tkinter a défini des constantes : RAISED='raised' SUNKEN='sunken' FLAT='flat' RIDGE='ridge' GROOVE='groove' SOLID='solid' : bordure régulière
Les grandeurs sont immédiatement traduites en pixels et l'utilisation d'unités explicites rend dépendant de l'écran utilisé.
* winfo_fpixels(dimension) : transforme la dimension en pixels sans arrondi * winfo_pixels(dimension) : arrondit le résultat précédent exemple :
4. l'attribut bitmapLes widgets tels que Button ou Label ont un attribut bitmap qui est exclusif de text mais est lui-même supplanté par image. Il s'agit par commodité de dix images au trait, garanties par tkinter, et qui s'adaptent à la coloration donnée par l'attribut foreground (noir par défaut). La valeur de l'attribut la chaîne d'identification du dessin. L'usage de l'UNICODE et des images a rendu très marginal l'utilisation de cet attribut pour les étiquettes. labelTxt7 = Label(monCadre, bg="#d0d0ff", text="questhead",font=maFonte) labelBt7 = Label(monCadre, bg="white", bitmap="questhead" ) Sous Linux, on peut utiliser un fichier au format xbm ; faire précéder le path du fichier d'un @. Sous Windows, voir avec un *.ico valide. arrow, based_arrow_down, based_arrow_up, boat, "bogosity, bottom_left_corner, bottom_right_corner, bottom_side, bottom_tee, box_spiral, center_ptr, circle, clock, coffee_mug, cross,cross_reverse, crosshair, diamond_cross, dot, dotbox, double_arrow, draft_large, draft_small, draped_box, exchange, fleur, gobbler, gumby, hand1, hand2, heart, icon, iron_cross, left_ptr, left_side, left_tee, leftbutton, ll_angle, lr_angle, man, middlebutton, mouse, pencil, pirate, plus, question_arrow, right_ptr, right_side, right_tee, rightbutton, rtl_logo, sailboat, sb_down_arrow, sb_h_double_arrow, sb_left_arrow, sb_right_arrow, sb_up_arrow, sb_v_double_arrow, shuttle, sizing, spider, spraycan, star, target, tcross, top_left_arrow, top_left_corner, top_right_corner, top_side, top_tee, trek, ul_angle, umbrella, ur_angle, watch, xterm Cependant, sur les systèmes Windows, on ne trouve que : arrow, center_ptr, crosshair, fleur, ibeam, icon, sb_h_double_arrow, sb_v_double_arrow, watch, xterm qui sont natifs. Les curseurs suivants sont également disponibles :
, size, size_ne_sw, size_ns, size_nw_se, L'attribut cursor prend comme valeur une chaîne qui est le nom d'un curseur valide. Il faut faire tk01 : valeurs d'attributs standards attention dès que l'on n'utilise pas des curseurs communs aux plate-formes car un nom de curseur non reconnu provoque une erreur. 6. justification des textes(les mêmes constantes servent pour les gestionnaire de placement Pack et Grid) LEFT='left' TOP='top' RIGHT='right' BOTTOM='bottom' CENTER="center" * StringVar (master=None, value=None) : master est un widget propriétaire, value une chaîne de caractères, valeur utile de la variable. Même chose pour IntVar() et DoubleVar(). méthodes : * set (valeur) : valeur peut être entier, flottant ou chaîne de caractères selon le type. La méthode fixe la valeur utile de la variable. * get () : retourne la valeur utile de la variable. * trace (mode, fonction) : appelle la fonction lorsque la variable change. Le mode est "r", (lecture), "w" (écriture), "u" (indéfini). Retourne une valeur cbtrace. * trace_variable (mode, fonction) : même chose que trace(). * trace_vdelete (mode, cbname) : efface la capacité d'appel posée par la méthode trace() qui avait retourné cbname. * trace_vinfo() : retourne toutes informations sur les appels de fonction posés par trace tk01 : valeurs d'attributs standards tk02 : BitmapImage et PhotoImage1. questions de formats1.1. l'attribut imageLes widgets Label, Button, Canvas, Text permettent d'insérer une image. Il existe deux types d'instances qui peuvent être valeurs d'un attribut image de ces widgets : les instances de BitmapImage, les instances de PhotoImage. 1.2. modes d'une image bitmapOn rappelle qu'il existe essentiellement quatre modes possibles pour une image en mode bitmap : - le mode trait : les pixels peuvent prendre deux valeurs. Le pixel est codé sur un bit, qui peut donc prendre les valeurs 0 ou 1. Le pixel à 0 est dit de couleur de fond et le pixel à un est dit noir. Le résultat à l'affichage dépend de l'afficheur ; en général la couleur de fond est la transparence, et les pixels noirs sont opaques. Mais on peut très bien avoir deux teintes quelconques pour le fond et l'opacité. - le mode monochrome, ou en niveaux de gris. Le pixel est codé sur 8 bits, et il y a 256 niveaux de gris, allant du blanc (codé 0) au noir (codé 255). - le mode palette. Il existe une palette de 256 teintes codées sur 3 octets ; chaque pixel est codé sur un octet, qui est la référence à une teinte de la palette. Les teintes de la palette peuvent être quelconques, et l'une d'elle peut être une transparence. tkinter connaît ces quatre modes, même s'il utilise en interne un mode RGB sur 6 octets. 1.3. question de fichierLes classes BitmapImage et PhotoImage utilisent dans leur constructeur la référence à un fichier image, permettant ainsi de passer d'un fichier à la valeur de l'attribut image ou bitmap lui correspondant. Seulement, si tkinter est capable de traiter les 4 modes, il n'accepte en entrés qu'un format de fichier graphique pour chaque mode : - pour le mode trait : les fichiers xbm - pour le mode monochrome : les fichiers pgm - pour le mode trichrome : les fichiers ppm (aussi appelés pnm ; c'est le nombre magique qui est vérifié) - pour le mode palette : les fichiers gif Comme ces formats sont parfaitement traités par les éditeurs graphiques comme GIMP, il n'y a donc aucun problème pour les fichiers d'images associés à une application. Noter le tramage de l'image au trait Pour un travail dynamique, il n'en est plus de même, et il est nécessaire de faire appel à une librairie spécialisée, ce qui ne devrait pas poser de problème avec la librairie PIL, sauf qu'en ce début 2013, la librairie PIL compatible avec Python 3x n'existe pas encore. La version 8.6. de tkinter devrait accepter les formats .png, ce qui serait une actualisation importante. 1.4. un exemple
2. la classe BitmapImage3.1. syntaxe variable = BitmapImage(options) 3.2. les options
3.3. les méthodes* config (options), configure (options) : permet de poser des options * width () : retourne un entier, largeur de l'image bitmap * height( ) : retourne un entier, hauteur de l'image bitmap * type : retourne "bitmap" 3. la classe PhotoImage3.1. syntaxe variable = PhotoImage(options) 3.2. les options
3.3. les méthodesparamètres * config (options), configure (options) : permet de poser des options * width () : retourne un entier, largeur de l'affichage de l'image * height () : retourne un entier, hauteur de l'affichage de l'image * type : retourne "photo" pixels * get (x,y) : retourne un chaîne ; en mode monochrome, elle contient la valeur du pixel, en trichrome, la suite des composantes RGB, avec l'espace comme séparateur. * put (data) , put (data, to=None): écrit une séquence de pixels colorés dans l'image, en commençant à la position to : ("{red green} {blue yellow}", to=(4,6)) * blank () : change le contenu de l'instance en rendant le contenu transparent. * write (fichier, format, from_coords) : écrit un fichier gif ou pgm à partir d'une instance de PhotoImage ; fichier est le chemin du fichier, format est "gif" ou "pgm", from_coords un tuple du cadre à découper et écrire. Si le tuple comporte deux entiers, le cadre commence au point de coordonnées précisé et va jusqu'en bas à droite. Si il en comporte 4, les deux derniers sont les coordonnées de la fin du cadre. imgPPM =PhotoImage(file="") imgPPM.write("","gif",(8,8,70,70)) copies * copy () : duplique l'instance de PhotoImage et retourne le duplicata. changements d'échelle * zoom (x, y) : retourne une instance de PhotoImage où chaque colonne est dupliquées x fois et chaque ligne y fois. x et y sont des entiers. Si y est absent ou "", alors y est pris égal à x. (8).subsample(3) labelImgPPM =Label(monCadre,image = imgZoom,font=maFonte) Il n'y a pas à proprement parler de changement d'échelle au sens où on l'entend dans les outils graphiques (GIMP, PIL). Il n'y a aucune interpolation, et le résultat obtenu en permutant les deux fonction est très différent. Il faut éviter d'encombrer la mémoire avec des objets trop gros. Les deux fonctions ont simplement pour vocation de permettre l'ajustement d'une image ou d'un logo. 4. Un problème avec l'attribut «image»Il y a un problème dans Tkinter à propos de l'attribut image des widgets. C'est que la valeur prise par l'attribut n'est pas référencée dans le compteur d’occurrences de l'objet. Autrement dit, si on écrit image=monImage, le nombre d'occurrences de monImage dans l'environnement du script ne change pas ! 4.1. on considère le script suivant :
Si on déroule l'exécutions : - lignes 1 à 10 : RAS - ligne 11 à 16 : création de la classe - ligne 17 : création de monLabel comme instance de maClasseLabel ; appel de __init__() - ligne 14 : création de la variable locale monIcone ; appelons Python1 l'objet image. Il y a alors une référence sur Python1, la variable monIcone. - ligne 15 : image pointe sur Python1, mais sans changer le compteur d'occurrences ! C'est le bug. -ligne 16 : la fonction se termine, et monIcone n'existe plus ; Python1 passe au ramasse miettes. 4.2. traiter le bugL'anomalie ne se produit que pour les images ; cela doit être dû à la manière dont Tkinter gère ses images, comme ressource interne. Pour palier à cette déficience, la recette est simple : s'arranger pour qu'il y ait toujours une référence sur l'image, au moins tant que vit l'instance ce qui suggère un code de la forme :
Mais pour d'autres genre d'applications multi images, on pourrait avoir : tk02 : BitmapImage et PhotoImage
tk02 : BitmapImage et PhotoImage tk03 : les fontesL'accès aux fontes se fait de deux façons : - soit en utilisant des descripteurs de fontes ; les descripteurs son connus du cœur de tkinter et ne nécessitent de passer par un module importé. C'est l'usage commun. - soit en utilisant une instance de la classe Font, qui est un module à importer. Le module Font comporte des propriété supplémentaires et il est requis pour un travail plus approfondi. 1. descripteur de fonteLa valeur d'un attribut fonte se code communément comme un descripteur de fonte
1.2. valeur de fonte : les descripteurs de fonte* valeur de fonte dans un tuple La première méthode est de décrire la fonte par un tuple d'au plus trois éléments : (famille, taille, modificateurs). - Famille et modificateurs sont des chaînes et taille un entier. - si le tuple a un seul élément, c'est la famille, deux éléments, la famille et la taille. - la taille est présumée être en points ; une taille en pixels s'exprime par un entier négatif. - Les paramètres de la chaîne des modificateurs sont dans un ordre indifférent, séparés par des espaces.
* valeur de fonte dans une liste Le tuple peut être remplacé par une liste de structure identique. La fonte devient alors modifiable. (Ne pas oublier qu'on ne peut pas modifier un tuple) * valeur de fonte dans une chaîne Le tuple peut être transformé en une chaîne unique. le séparateur est alors l'espace ; mais il y a un problème avec les noms de famille qui contiennent déjà des espaces ; on les met alors entre accolades. maFonte ="Courier 30 bold" maFonte ="{Deja Vu Sans Light} -30 underline" note : En ce qui concerne le nom de famille des fontes, la casse n'est pas significative. Il n'en est pas de même avec les modificateurs, impérativement en minuscules. En principe, les fontes Sans, Sérif, et Monospace sont des fontes vectorielles (True Type, Post Script). La fonte System est la fonte par défaut du système, dont les caractères son en bitmap, et où seulement certaines tailles sont disponibles ; dans le cas où la taille n'est pas disponible, c'est la taille la plus voisine qui est retenue. Il est recommandé d'utiliser les fontes présentes sur les plate-forme actuelles comme DejaVu : maFonte = ("Deja Vu Sans Light",-30) 2. Le module Font2.1. le constructeur FontLe constructeur permet de construire une instance de la classe Font, qui est la seconde forme de passage de valeur au paramètre font des widgets. Attention, cette instance n'est pas un descripteur de fonte ! Si on veut caster cet objet en descripteur, il faut lui appliquer la méthode usuelle en Python, toString() qui retourne la forme chaîne du descripteur. constructeur : maFonte = Font (options) 2.2. les options de FontLe options se présentent nécessairement sous la forme clef/valeur. * font : la valeur est un descripteur sous la forme tuple ; normalement si l'option font est présente, il n'y a plus d'autres options dans le constructeur. * name : permet de changer le nom de la fonte qui est octroyé par défaut. Le nom doit être unique dans le logiciel ! Ce paramètre ne devrait jamais être employé. * family : "Courier", "Times", "Helvetica" par défaut * size : entier qui fixe la taille en points ; négative pour une taille en pixels * weight : NORMAL ou BOLD * slant : ROMAN ou ITALIC * underline : booléen * overstrike : booléen 2.3. les méthodes d'instance de Font* copy () : retourne une autre instance, avec les mêmes options. * actual(), configure() : retourne un dictionnaire des attributs de la fonte * actual (nom d'options), cget(nom d'option) : retourne la valeur de l'option * configure (options clef/valeurs) : * measure (text) : retourne la largeur du texte en pixels. * metrics (noms d'options) : retourne les valeurs pour les «métriques». Pour ces deux méthodes, s'assurer que la fonte est utilisée au moins une fois avant de les appeler. 2.4. fonctions du module font* families () : retourne la liste des familles présentes sur la plate-forme. * names () : retourne la liste de noms de fontes définies dans l'application.
# boucle de la fenêtre principale fenPr.mainloop() fenPr.destroy() # par précaution # fichierle résultat : ( reformaté)
tk04 : géométriesLe terme de «géométrie» (geometry) recouvre tous les questions relatives au placement des éléments graphiques fenêtrés, les fenêtres de haut niveau (principale et Toplevel) et les autres widgets (boutons, cadres etc). La mise en place des composants est réalisée par un gestionnaire de fenêtre (window manager) qui est un arbitre de toutes les contraintes dimensionnelles proposées implicitement (contraintes d'un gestionnaire de placement, dimension de la fonte effectivement utilisée) ou explicitement (dimension requise pour un widget). exemple :"wxh+l+t" = "400x500+300+250" ; si on prend les bordure de la fenêtre en considération, remplacer les signes + par - ; exemple : "400x500-300-250" Note : il se peut que «l'écran» physique ne coïncide pas avec l'écran disponible. Cela dépend de l'interface graphique. La géométrie travaille avec l'écran disponible. La géométrie est caractérisé par la chaîne de géométrie . Son format est : "wxh±l±t"où w, h, et t sont des entier décimaux sans signe. 1.2. fixer la géométrie d'une fenêtreToute fenêtre a une géométrie par défaut, imposée par les gestionnaires de placement qui doivent trouver la place pour les composants ! Si l'affichage n'a pas eu lieu, la chaîne est "1x1+0+0". * la méthode geometry() d'une fenêtre de haut niveau permet de requérir un changement de géométrie. L'argument est une chaîne de géométrie. Attention : la géométrie d'une fenêtre subit les aléas du placement de ses widgets, et peut être remise en cause par les gestionnaires de placement des widgets, comme on le verra ultérieurement. 1.3. retrouver la géométrie d'une fenêtre* la méthode geometry() sans argument retourne la valeur actuelle de la géométrie. Mais la référence n'existe que si le gestionnaire de fenêtre a fait ses calculs ! - si la fenêtre est affichée, il n'y a pas de problème. - Mais, le plus souvent, on a besoin des renseignements de géométrie avant l'affichage, parexemple pour réaliser un centrage de popup. Il faut alors forcer le calcul, sans cependant provoquer l'affichage. La méthode update_idletasks() y pourvoit. Il existe des méthodes qui permettent d'accéder directement aux paramètres et sur lesquelles on reviendra dans le chapitre sur le gestionnaire de fenêtres. On peut citer : * winfo_width(), winfo_height() : retournent w et h * winfo_rootx(), winfo_rooty() : retourne les cordonnées du coin supérieur gauche de la fenêtre principale dans l'écran ;
2. Les gestionnaires de placement2.1. les trois gestionnairesUn gestionnaire de placement est une classe dont les méthodes permettent de placer un widget dans son maître (conteneur, master). Les conteneurs peuvent être les fenêtres de haut niveau ou les cadres (Frame). On verra dans l'étude des widgets Text et Canvas des cas où le placement ne se fait pas avec les gestionnaires de placement. Il existe 3 gestionnaires de placement : Pack, Grid, Place 2.2. règles d'usage * les widgets plaçables du noyau de tkinter sont les suivants : Frame, LabelFrame PanedWindow,Scrollbar, Label, Button,Checkbutton, Listbox, Radiobutton,Entry, OptionMenu, Text, Canvas,Scale, Spinbox. (ne sont donc pas plaçables : Tk(),Toplevel,Menu) Les widgets additionnels (tix, ttk) sont plaçables également. * les widgets plaçables héritent des trois classesPack, Grid, Place * si un gestionnaire de placement est utilisé dans une instance de conteneur, aucun autre gestionnaire ne peut être utilisé dans la même instance. Cette règle est souvent mal comprise : on peut très bien changer de gestionnaire quand on passe d'un conteneur à un de ses enfants. exemple : * la fenêtre principale est en noir . * les widgets en bleu utilisent le gestionnaire Pask * les widgets en rouge utilisent legestionnaire Place * les widgets en vert utilisent le gestionnaireGrid. 3. Le gestionnaire Pack. 3.1. fonctionnement du gestionnaire PackL'utilisation de ce gestionnaire est délicate dès qu'une interface est un peu complexe. Son interprétation est assez difficile à comprendre. Les enfants sont pris en charge dans l'ordre où ils se présentent, avec leur dimension. Ils sont placés sur le bord défini par side dans le «rectangle restant». Pour le premier enfant, c'est le conteneur tel qu'il est. L'enfant est placé, le conteneur s'ajuste. Si le premier enfant est placé sur le bord haut (TOP), le rectangle restant est dessiné en dessous, avec sa largeur. (ce serait à gauche pour RIGHT, à droite pour LEFT, au dessus pour BOTTOM). Le second enfant est alors placé avec pour conteneur le «rectangle restant) On continue ainsi, en tenant compte du remplissage éventuel ; les dimensions requises en cas de remplissage peuvent être perturbés. Le gestionnaire Pack dans un conteneur a pour effet de l'ajuster à ses composants sauf s'il y a une contrainte posée par le gestionnaire de son propre conteneur. La dimension proposée pour le conteneur n'est en général pas prise en compte ! Dans l'exemple suivant, le «rectangle restant» est symbolisé par un pointillé exemple
3.2. les méthodes de widget* pack(options) : c'est la méthode qui réalise le placement, suivant les options posées. * pack_configure(options) : définit la même méthode que pack() * pack_forget() : la méthodedétruit l'effet du gestionnaire de géométrie. Ceci implique que le widget existe toujours, mais qu'il n'est plus affiché et qu'un nouvel appel à la méthode pack() peut être envisagé. * pack_info() : la méthode retourne un dictionnaire des options.
3.3. les valeurs d'attribut :attributside LEFT='left' TOP='top' RIGHT='right' BOTTOM='bottom' attribut anchor pour pack N='n'NW='nw'CENTER='center' S='s'SW='sw' W='w'NE='ne' E='e'SE='se' attribut fill NONE='none' X='x' Y='y' BOTH='both' 3.4. les options
4. le gestionnaire Grid4.1. principe du gestionnaire GridLe gestionnaire Grid est plus simple à comprendre que le précédent : il rappelle le fonctionnement du placement par tableau dans le HTML. Le gestionnaire Grid, au premier appel dans un conteneur, crée un tableau dynamique (le nombre de lignes, de colonnes, leur dimension peuvent évoluer au fur et à mesure des appels) et place les widgets dans ce tableau, ajustant le tableau aux dimensions des widgets. En principe, on ne met qu'un widget par cellule ; si on en met plusieurs, ils se superposent facilement et le résultat est illisible. La hauteur d'une ligne est celle de la plus haute cellule de la ligne ; la largeur de colonne est celle de la plus large cellule de la colonne. Les lignes et colonnes sont numérotées (à partir de 0), et placées en ordre croissants ; les numéros n'ont pas besoin d'être consécutifs (par exemple, les lignes peuvent être numérotées de 10 en 10) ; un cellule peut rester vide. La cellule est ajusté à son contenu si une dimension est insuffisante. Mais il est fréquent qu'une cellule soit plus grande que son contenu ; il est donc important de pouvoir ancrer le widget dans sa cellule. Ici également, le conteneur est ajusté, mais au tableau résultant. Les programmeurs utilisent volontiers ce gestionnaire, et même recommandent de n'utiliser que lui seul (Shipman). 4.2. les méthodes de Grid méthodes concernant le widget * grid(options) : la méthode est la méthode appelée pour placer le widget * grid_configure(options) : la méthode est identique à grid(options). * grid_info() : la méthode retourne un dictionnaire des options. méthodes concernant la grille * columnconfigure(N, options de configuration de grille) : permet à la colonne N d'échapper aux valeurs de dimension par défaut. * grid_box(column=None, row=None, col2=None, row2=None) : * grid_location(x, y) : retourne un tuple donnant la ligne et la colonne du point de coordonnées (x, y) du widget. * grid_size() : retourne le nombre de lignes et de colonnes dans un tuple. * grid_slaves(row=None, column=None) : énonce la liste des widgets esclaves * grid_forget() : la méthode est identique à celle de Pack, avec perte de la configuration de grille. * grid_remove() : la méthode est semblable à grid-forget(), sans perte de la configuration de grille. 4.3. les options de configuration de grille
4.4. les options de cellule*Les options padx, pady, ipadx, ipady, in_ sont les mêmes que pour Pack * l'option sticky qui renseigne sur la manière de "coller" le widget aux bords si la cellule est trop grande.
exemple :
5. Le gestionnaire Place5.1. principe du gestionnaire PlaceLe gestionnaire Place est le plus simple des gestionnaires de placements ; il permet de placer un widget en explicitant des coordonnées (centre, coins..) soit en position absolue, soit relativement à un élément fenêtré existant. Il permet en outre de fixer explicitement les dimensions du widget. 5.2. les méthode du gestionnaire Place* place(options) : la méthode place et dimensionne le widget selon les options choisies. * place_configure(options) : identique à place(options) * place_forget() : même chose que pour Pack * place_info() : même chose que pour Pack et Grid * place_slaves() : retourne la liste des widgets «esclaves». 5.3. le valeurs d'optionsINSIDE='inside' OUTSIDE='outside' 5.4. les options
tk04 : géométries
6. la troisième dimension6.1. empilement des «calques»Pour modéliser l'affichage dans un interface graphique, on peut adopter la métaphore d'un empilement de calques : toute fenêtre est un graphisme rectangulaire sur un calque indéfini transparent ; tout widget est aussi un graphisme rectangulaire sur un calque. Le calque de chaque widget est lié a la fenêtre dans laquelle il a été défini. Les calques de widget sont empilés dans l'ordre de leur définition, le plus récent étant au dessus. De même les fenêtres d'une application sont empilées dans l'ordre de leur définition graphique (de leur affichage). Il en est de même des applications. Ce modèle permet de comprendre comment se fait l'affichage : le pixel affiché est le pixel qui se situe le plus «au dessus» lorsque l'on passe en revue tous les calques dans l'ordre d'empilement (par défaut, du plus ancien au plus récent). Cet ordre d'empilement peut être modifié ; on sait qu'une fenêtre qui prend le focus se met immédiatement au dessus de toutes les autres. 6.2. Les méthodes* lift(aboveThis=None) : élève la fenêtre de haut niveau dans la pile des fenêtres au-dessus de aboveThis. Sans argument, met la fenêtre au sommet de la pile. (aboveThis est une instance de Tk ou Toplevel). Appliquée à un widget plaçable, elle permet de manipuler les superpositions de widget d'un même conteneur. * lower(belowThis=None) : descend la fenêtre de haut niveau dans la pile des fenêtres en dessous de belowThis. Sans argument, met la fenêtre en bas de la pile. (aboveThis est une instance de Toplevel ou Tk). Appliquée à un widget plaçable, elle permet de manipuler les superpositions de widget d'un même conteneur. "modale" une fenêtre dans une application simple, c'est-à-dire qu'elle apparaît en haut de la pile car elle capture le focus et reste liée avec son parent. Voir tk08 §3.4 Tk et Toplevel tk04 : géométries tk05 : attributs partagésLes paramètres des widgets, fixés à la création ou par le programme sont appelés ses attributs. De nombreux attributs sont partagés par une partie, voire tous les widgets (les attributs standards) de tkinter. Ce sont ces attributs qui vont être décrits ; ceci évitera de nombreuses redites. Les attributs très spécifiqueset n'appartenat qu'à un widget seront abordés dans la description de chacun d'eux : Canvas, Text . 1. méthodes d'attributs1.1. attributs donnés à un widget* tous les attributs d'un widget ont une valeur par défaut, qui peut varier selon les widgets. * tous les attributs d'un widget peuvent être des arguments (facultatifs) de son constructeur ; le constructeur d'un widget est de la forme Widget(constucteur, options). Ou de son gestionnaire de placement, appelé sous la forme widget.gestionnaire(options). Ou encore des deux, comme padx ou pady. monCadre = Frame(fenPr, bg="#b0b0ff", borderwidth=3, relief=GROOVE) 1.2.modification d'un ou plusieurs attributs* config(options) : méthode qui modifie des options du widget * configure(options) : méthode qui double config(options) # change l'image et le fond d'un labellabelPhoto.config( image = imgGIF, bg="#b0b0ff") On peut modifier les attributs par une affectation sur le modèle suivant : labelPhoto ["image"] = imgGIF labelPhoto ["background"] ="#b0b0ff" 1.3. accès aux attributs* config() : retourne un dictionnaire de tous les attributs d'un widget. * configure() : doublé de config(). On peut aussi accéder aux attributs en utilisant la notation «dictionnaire» : print (labelPhoto ["background"])
,3) 'class': ('class', 'class', 'Class', 'Frame', 'Frame'), 'colormap': ('colormap', 'colormap', 'Colormap', '', ''), 'container': ('container', 'container', 'Container', 0, 0), 'cursor': ('cursor', 'cursor', 'Cursor', '', ''), 'height': ('height', 'height', 'Height', , 0), 'highlightbackground': ('highlightbackground', 'highlightBackground', 'HighlightBackground', , '#d9d9d9'), 'highlightcolor': ('highlightcolor', 'highlightColor', 'HighlightColor', , '#000000'), 'highlightthickness': ('highlightthickness', 'highlightThickness', 'HighlightThickness', , 0), 'padx': ('padx', 'padX', 'Pad', , ), 'pady': ('pady', 'padY', 'Pad', , ), 'relief': ('relief', 'relief', 'Relief', , 'groove'), 'takefocus': ('takefocus', 'takeFocus', 'TakeFocus', '0', '0'), 'visual': ('visual', 'visual', 'Visual', '', ''), 'width': ('width', 'width', 'Width', , 0), } La structure de ce dictionnaire des options est assez complexe : * les clefs sont les dénominations d'attributs * les valeurs sont des tuples, selon deux modes : - certains tuple définissent un alias : 'bd': ('bd', '-borderwidth'), - les autres l'attribut sous forme d'un tuple à 5 éléments Le premier élément du tuple est la clef ; * cget(clef) : retourne une chaîne de caractère donnant la valeur actuelle ; attention, un entier ou un flottant sont convertis en chaîne. Les booléens suivent la convention du C (0/1) * keys() : retourne une liste des clefs des attributs disponibles.
2. attributs système* class : c'est la classe du widget. Attention, class est réservé en Python et il faut écrire class_ pour tous usage que l'on peut en faire. Par défaut, la classe est le type de widget, on peut définir des classes plus étendue que l'on utilise pour les options de classe de widget, qui portent sur ces "classes". * command : référence le gestionnaire d'événement (par exemple pour Button) * cursor : référence le curseur à utiliser lors d'un survol du widget. * takefocus : spécifie si un widgetest autorisé à recevoir le focus (il est focusable) ou non. La valeur est 0 (True) ou 1 (False). La valeur par défaut dépend du type de widget. 3. attributs de bordure et de margeTous les widgets possèdent les deux premiers attributs de bordure. * borderwidth : largeur (integer) de bordure (défaut 1 ou 2 pixels), en pixels * relief : la forme de la bordure (voir les constantes de relief) pour un widget à l'état normal. La valeur par défaut dépend du widget (FLAT pour label, GROOVE pour un cadre, RAISED pour un bouton) et peut dépendre de l'état du widget si celui-ci en a plusieurs possibles. * highlightthickness : largeur de surbordure lors lors d'une prise de focus. * padx, pady : espacements à ajouter au widgets à l'intérieur de la bordure lors du placement. Il s'agit ici de paramètres de configuration, pas des paramètres de placement ! * width : largeur souhaitée du widget ; peut être exprimé en unité de dimensions. Pour certains widgets ayant un attribut text (Entry, Button etc.) la largeur s'exprime en nombre de caractères. * height : hauteur souhaitée du widget ; peut être exprimé en unité de dimensions. 4. attributs de couleur. * background, bg : couleur de fond ; partagé par tous les widgets. * foreground, fg : couleur de caractère ; partagé par les widgets acceptant du texte ou un bitmap. * highlightbackground : couleur de surbordure qui na pas le focus ; * highlightcolor : couleur de la surbordure qui a pris le focus). * disabledforeground : couleur de fond à accorder aux éléments rendus inactifs par (state="disabled"). * colormap : palette pour les écrans anciens. 5. attributs pour les gestionnaires de géométrie (rappel)Partagés par tous les widgets. * in (in_) : permet de placer un widget relativement à un descendant de ses parents ; option du gestionnaire de placement. * relwith : largeur souhaitée du widget ; valeur relative au conteneur (gestionnaire Place) * relheight : hauteur souhaitée du widget ; valeur relative au conteneur (gestionnaire Place) * sticky : ancrage dans le gestionnaire Grid * anchor :ancrage dans les gestionnaires Pack et Place * row : numéro de ligne dans le gestionnaire Grid. * column : numéro de lcolonne dans le gestionnaire Grid. * rowspan : fusion de lignes dans le gestionnaire Grid. * padx, pady : espacements à ajouter au widgets à l'extérieur de la bordure lors du placement. * columnspan : fusion de colonnes dans le gestionnaire Grid. * x : offset écran horizontal de l'ancre (gestionnaire Place) * relx : offset relatif horizontal dans le conteneur de l'ancre (gestionnaire Place) * y : offset écran vertical l'ancre (gestionnaire Place) * rely :offset relatif vertical dans le conteneur de l'ancre (gestionnaire Place) 6. les attributs default et stateLes widget de commande, comme Button, Chekbox, Entry, Radiobutton etc. peuvent avoir trois états : Ils peuvent être vivants/normaux, vivants/actifs, ou paralysés. À chacun de ces états correspond un aspect particulier du widget. * state : l'attribut state a lui aussi trois valeurs : "normal ","active" et "disabled". Le plus souvent, le passage à "active" se fait automatiquement lorsque la souris survole le widget et l'attribut state n'a pas lieu d'être changé par programme pour cela. * L'attribut defaut n'existe plus que pour les boutons dans tkinter 8.5. Et il a changé de signification ; il a deux valeurs utiles "normal" et "active" correspondant à une bordure en creux. tkinter connaît des constantes de circonstance : ACTIVE = "active NORMAL = "normal" DISABLED = "disabled" L'attribut "readonly" n'a pas de constante associée. 7. l'attributcommand. Cet attribut est partagé par les widgets qui réagissent à une cause extérieure : le bouton cliqué, la checkbox cochée ou décochée, le radio-bouton inversé etc. Dans ce cas, les widgets disposent de l'attribut command qui peut prendre comme valeur soit une fonction nommée et dans ce cas le nom de la fonction lui est attribué (attention, ce n'est pas une chaîne mais un identificateur) soit une lambda-fonction. command = maFonction command =self.maMethode command = lambda x : monExpression - Pour un bouton, la fonction nommée ne peut pas contenir de paramètre non initialisé. Elleest appelée sans paramètre valeur lorsque la commande s'active. - On rappelle qu'une lambda-fonction peut comporter un ou plusieurs paramètres et une seuleexpression. Elle retourne le résultat de l'évaluation de l'expression (éventuellement rien). La lambda fonction peut être une façon d'appeler un gestionnaire, en lui passsant des paramètres particuliers à l'instance d'appel. Cela sera détaillé pour chaque cas d'espèce. 8. attributs de désaffection (disable)Les widgets de saisie de données peuvent être temporairement désaffectés, indiquant par là qu'ils ne peuvent être utilisés, mais tout en restant présents à l'affichage. Celui-ci est cependant marqué par des couleurs particulières, qui montrent à l'utilisateur qu'il ne sont pas en activité, où qu'ils sont en consultation seulement (readonly). * disabledbackground : la couleur de fond en cas de non activité. * disabledforeground : la couleur de caractères en cas de non activité. * readonlybackground : le widget qui était habituellement en saisie clavier avec écho (ce que l'on a frappé au clavier apparaît à l'écran), a perdu sa capacité de saisie, ce qui n'empêche pas l'affichage, la sélection et le coller de sélection. tk06: les méthodes partagéesLe fait pour un objet de tkinter d'être un widget implique que l'instance partage toutes les méthodes de la classe Widget. On a déjà vu une partie de ces méthodes pour le placement ou les méthodes touchant aux attributs. On les rappellera pour mémoire. Il est important aussi de savoir qu'il n'y a pas de fonctions globales spécifiques de l'interface graphique dans thinter. Toutes ces fonctions sont donc attachées à un widget, aussi étonnant que cela puisse paraître pour des fonctions concernant la temporisation, les caractéristique de l'écran ou simplement le codage des couleurs. 1. méthodes portant sur les attributs1.1. méthodes de configurationOn revoie au chapitre tk05 §1 atttributs pour plus de détails. * config(options), configure(options) : méthode qui modifie des options du widget * config(), configure() : sans argument, la méthode retourne un dictionnaire de tous les attributs de constructeur d'un widget. * cget(clef) : retourne une chaîne de caractère donnant la valeur actuelle ; attention, un entier ou un flottant sont convertis en chaîne ou objet interne, convertible en chaîne par str(). Il peut y avoir difficulté avec "height" par exemple, ou le retour est un objet interne (voir PanedWindow) à transformer par str() puis int() si on veut par exemple un nombre de pixels. Les widgets étant subsriptable pour les attributs, on utilise de façon équivalente la notation avec crochets ((clef) équivaut widget["clef"]) * keys() : retourne une liste des clefs des attributs disponibles. * image_name() : énonce la suite des noms d'image (il s'agit des noms internes donnés par l'application) dans l'application du widget dans une chaîne. * image_types() : énonce de même les types utilisés( bitmap ou photo) 1.2. méthodes d'options de classesOn peut modifier les valeurs par défaut des attributs de widget. Pour cela il faut décrire l'option dans le format Xdefaults, qui sert à coder les options globales. Le format est le suivant "*classe*option". Avec tkinter on a par exemple "*Button*font" ou "*Toplevel*background". On peut définir des classes non standard avec l'attributy class (écrire class_). Voir chapitre tk05 §2 * option_add(option, valeur, priority=None) : option est l'option au format Xdefault et valeur la valeur de l'option : exemple : fenPrincipale.option_add("*Frame*background","red") * option_clear() : supprime toutes les options utilisateur ; retourne aux valeurs par défaut. * option_get(nom_option, classe_widget) : la méthode retourne la valeur de l'option. * option_readfile(fileName, priority=None) : permet d'ajouter des options enregistrées dans un fichier au format Xdefaut. Chaque ligne comporte une option suivie de sa valeur : tk06: les méthodes partagées par exemple : *Frame*background red 2. méthodes concernant les événementsLes méthodes suivantes font l'objet d'une notice dans le chapitre tk07 événement. bind, bind_all, bind_class unbind, unbind_all, unbind_class,bindtags, event_add, event_delete, event_generate, event_info 3. méthodes de presse-papier* clipboard_get() : retourne les données du presse_papier de Tk * clipboard_append(text) : ajoute le texte text au contenue du presse papier de Tk * clipboard_clear() : vide le presse papier * selection_clear() : supprime une éventuelle sélection. * selection_get() : s'il y a une sélection de texte sur le widget, retourne cette sélection. Lève une erreur sinon. * selection_own() : le widget d'appel devient propriétaire de la sélection actuelle. * selection_own_get() : retourne la sélection dont le widget est propriétaire. Lève une erreur sinon. 4. méthodes relatives aux placements4.1. gestionnaires de placementgrid, column_configure, row_configure, grid_forget, grid_remove, grid_propagate, pack, pack_forget, place, place_forget, Ces méthodes font l'objet d'une notice dans le chapitre tk04 Géométries * winfo_ismapped() : le widget d'appel est soumis à un gestionnaire de placements, ainsi que tous ceux qui le contiennent jusque sa fenêtre de haut niveau. C'est évidemment le cas si celle-ci est affichée ; dans le cas contraire, invoquer update_idletasks(). * winfo_vewable() : la méthode retourne un booléen qui indique si le widget d'appel ainsi que la chaîne de ses propriétaires est mappée. * winfo_manager() : si le widget n'a pas de gestionnaire de géométrie, la méthode retourne une chaîne vide. Dans le cas contraire, c'est une des chaînes suivantes : "grid", "pack", "place", "canvas" ou "text". Une fenêtre de haut niveau retourne "wm". * pack_info(), grid_info() et place_info() : voir section 1 4.2. empilement des widgets* lift(), lower() : Voir le chapitre tk04 Géométries * transient(master) : voir le chapitre tk08 §3.4 Tk et Toplevel * winfo_geometry() : Voir le chapitre tk04 Géométries 5. mesures relatives au widget* winfo_height() : la méthode retourne la hauteur du widget tel qu'il est ou sera affiché. Cette donnée n'est à jour que si aucun calcul latent n'est en cours : lorsque le widget est affiché, c'est sûr. On peut forcer les calculs de géométrie (ceux qui servent à l'affichage après négociation avec les gestionnaires de placement) en appelant la méthode update_idletasks(). * winfo_width() : la méthode retourne la largeur du widget tel qu'il est ou sera affiché. Cette donnée n'est à jour que si aucun calcul latent n'est en cours. On peut forcer les calculs de géométrie (ceux qui servent à l'affichage après négociation avec les gestionnaires de placement) en appelant la méthode update_idletasks(). * winfo_x() : la méthode appliquée à un widget w retourne l'offset horizontal (en pixels) de w par rapport à son propriétaire. Le calcul se fait sur l'extérieur de la bordure de w. Voir les remarque sur winfo_with() qui s'appliquent ici. * winfo_y() : la méthode appliquée à un widget w retourne l'offset vertical (en pixels) de w par rapport à son propriétaire. Le calcul se fait sur l'extérieur de la bordure de w. Voir les remarque sur winfo-with() qui s'appliquent ici. * winfo_reqheight() : retourne la hauteur requise pour un widget, celle en deçà de laquelle le widget ne peut être affiché en entier. Il s'agit de la dimension calculée avant qu'un gestionnaire de placement lui soit appliqué. La dimension réelle après affichage peut ne pas correspondre. exemple : # label de la questionquestion =Label(self, font=Kt.fonte, text=message) wr = question.winfo_reqwidth() hr = question.winfo_reqheight() * winfo_rootx() : retourne l'offset écran du bord gauche du widget, bordure comprise. Demande que l'affichage soit effectif. * winfo_rooty() : retourne l'offset écran du bord haut du widget, bordure comprise. Demande que l'affichage soit effectif. * winfo_containing(rootx, rooty, displayof=0) : la méthode retourne le widget qui a le point de coordonnées écran rootx et rooty ; si displayof est False, la recherche se fait par rapport à la fenêtre Toplevel du widget d'appel ; sinon, par rapport à la racine de l'application. Retourne None éventuellement. 6. méthodes portant sur la console* winfo_screenheight() : cette méthode retourne la hauteur de l'écran en pixels. La forme de l'appel est donc widget.winfo_screenheight() ; ce qui suppose qu'au moment de l'appel il existe au moins un widget. Or, on peut avoir besoin de l'information dans un module, ou avant toute création de widget. On peut procéder ainsi pour créer une fonction screenHeight() :
defscreenHeight () : return tkinter.Frame().winfo_screenheight() * winfo_screenwidth() : cette méthode retourne la hauteur de l'écran en pixels. Voir winfo_screenheight()pour un appel indépendant de l'environnement. * winfo_screenmmwidth() : cette méthode retourne la hauteur de l'écran en millimètres. Idem. * winfo_screenmmheight() : cette méthode retourne la hauteur de l'écran en millimètres. Idem. * winfo_screenvisual() : cette méthode retourne le type modèle de couleur par défaut (celui de l'écran). truecolor pour le mode trichrome 24 bits par pixel. Autres valeurs : directcolor, grayscale, pseudocolor, staticcolor, staticgray. Méthode devenue désuette. * winfo_depth() : retourne le nombre de bits par pixels utilisés dans l'application. Voir chapitre tk01 § 3.1.méthodes de widget. * winfo_fpixels(dimension) : transforme la dimension en pixels sans arrondi. Voir chapitre tk01 §3 unités * winfo_pixels(dimension) : arrondit le résultat précédent. * bell() : la méthode provoque l'émission d'un bip. 7. méthodes de souris* winfo_pointerxy() : la méthode retourne un tuple d'entier qui sont les coordonnées (offsets horizontal et vertical) de la souris dans la fenêtre Tk ou Toplevel du widget * winfo_pointerx() : retourne l'offset horizontal de la souris * winfo_pointery() : : retourne l'offset vertical de la souris 8. les bouclesEn programmation, une boucle est une séquence exécutée de façon itérative. Une boucle mobilise le processeur : il est donc souhaitable d'avoir un moyen de l'interrompre, sinon c'est le plantage bien connu et redouté de la «boucle infinie». Cependant, les langages pour interfaces graphiques proposent des boucles indéfinies, mais qui ne sollicitent pas le processeurs de façon exclusive. Il y a deux type de boucles : * le boucle principale du programme ; deux méthodes lui sont associées, mainloop() et quit(). La méthode mainloop() est bloquante c'est-à-dire qu'il faut un événement extérieur pour que l'instruction qui suit son appel soit exécutée, en l'occurence l'appel de la méthode quit(). * les boucles locales. Une boucle locale est une boucle d'attente qui est bloquante en l'attente d'un événement qu'elle est capable de détecter, mais qui est «indolore» pour tout l'environnement. Les événements restent accessibles à la boucle principale : Le bloquage n'empêche pas le système de surveillance d'événement de fonctionner, ni les gestionnaires d'événement de s'exécuter, ni le gestionnaire de fenêtre de fonctionner. inverse des appels. Il est cependant rare que le besoin se fasse sentir de quitter la méthode mainloop(), sauf pour mettre fin proprement à l'application, ce qui explique la recommandation du chapitre 0. * quit() : met fin à la méthode mainloop dernière appelée. exemple :
* wait_variable(v) : crée une boucle d'attente locale ; la séquence en exécution est stoppée tant que la variable v n'a pas été affectée (une affectation du type v=v est parfaitement valide). v doit être entier, flottant, chaîne, booléen. * wait_visibility() : méthode réservée aux widget Tk et Toplevel. Elle crée une boucle d'attente locale ; la séquence en exécution est stoppée tant que le widget n'est pas visible. exemple :
9. méthodes de gestion du déroulement de programme. * destroy() : détruit sans recours le widget d'appel. * update() : la méthode met à jour tout ce qui est latent : les gestionnaire d'interruption non encore appelés, calcul et tracé des widgets qui doivent être redessinés, réaffichage de l'application à l'écran. Cette méthode doit être utilisée avec précaution, surtout si elle est appelée depuis un gestionnaire d'événements, car il est parfois difficile de prévoir ce qui va se passer (à cause des gestionnaire d'événement qui sont sollicités à l'affichage). * update_idletasks() : cette méthode ressemble à la précédente, sauf en ce qui concerne l'affichage et les événements ; en effet, si l'affichage est recalculé, il n'est pas sollicité et les gestionnaires d'événements éventuellement en attente ne sont pas exécutés. Cette méthode doit être utilisée chaque fois que l'on a besoin de données qui ne sont normalement calculées qu'à l'affichage de l'application (par exemple, les dimensions des composants d'une fenêtre popup non affichée). Attention cependant à un forçage des calculs par update_idletasks() alors que tous les éléments contribuant au placement ne sont pas encore négocié, par exemple avant un appel de la méthode transient(). Le forçage peut perturber la géométrie des éléments. * after(delay_ms, callback=None, *args) : delay_ms st un entier et callback une fonction. La fonction callback() est appelée après au moins delay_ms * after_cancel(id) : id est l'identificateur renvoyé par after(). La temporisation initiée par after() est abandonnée et la fonction callback() n'est pas appelée. * after_idle(func, *args) : la fonction func(), avec les arguments args est appelée lorsque tous les gestionnaire d'événement en instance sont exécutés. 10. méthodes d'identificationChaque widget a par défaut un nom unique dans l'application, chaîne qui peut être changé lors de la création du widget. Il dispose également d'un identificateur, qui est un entier. Il dispose également d'un pathname qui est la succession des noms de conteneurs lorsque l'on remonte du widget à l'application racine (le nom de celle-ci n'est pas affichée). Ces noms son séparés par un point et le pathname commence donc par un point ! * winfo_id() : la méthode retourne l'identificateur du widget d'appel * winfo_name() : la méthode retourne le nom du widget d'appel * winfo_pathname(id, displayod=False) : id est l'identificateur du widget dont on veut le pathname. Le widget d'appel est indifférent. Le pathname est parfois appelé le nom complet du widget, et il est aussi retourné par la fonction str(widget). La forme de la chaîne est : ".nom_toplevel.nom_cont1.nom_cont2.nom_widget" s'il y a 2 conteneurs. Le nom est par défaut la suite de chiffre donnée par le système ; si on a utilisé name dans le constructeur, c'est le nom utilisateur. * winfo_toplevel() : la méthode retourne le Toplevel qui contient le widget d'appel. * winfo_parent() : la méthode retourne le pathname du conteneur immédiat du widget d'appel. (attention, ne retourne pas le parent !) * winfo_children() : la méthode retourne une liste des enfants du widget d'appel. Cette fois, ce sont bien les widgets qui sont retournés ! * winfo_class() : la méthode retourne le nom de la classe du widget. exemple :
forenfantinself.winfo_children() : print ("enfant du TopLevel :", enfant, "de classe :", enfant.winfo_class()) print ("classe de self :",self.winfo_class())
defmarkUp(event=None) : monEntree.scan_mark(30) monEntree.scan_dragto(35) defmarkDown(event=None) : monEntree.scan_mark(30) monEntree.scan_dragto(25) ("", markUp) ("", markDown) racine.mainloop() racine.destroy() # fichier résultat : 5. problème de validation : un exempleschéma de principe : Les lignes de code qui suivent ne constituent qu'un schéma de principe pour le problème suivant : ne saisir au clavier que les caractères majuscules, à l'exclusion de tout autre, y compris Back-Space. * On utilise le fait que la capture d'événement est prioritaire sur tout appel de commande, ce qui permet de saisir la touche clavier activée et de traiter le filtrage ensuite. * le script serait déficient avec un copier coller. * par une curiosité non documentée, l'appel du gestionnaire validatecommand() dans l'exécution du gestionnaire invalidcommand() remet l'attribut validate à "none". ce qui explique la nécessité de reformuler le validate="key" dans toucheClavier().
tk20 : TextLe widget Text permet de créer un éditeur de texte formaté dans un programme : on peut utiliser plusieurs fontes et plusieurs couleurs. On peut incorporer une image qui est alors considérée comme un caractère unique. On peut aussi introduire des marqueurs invisibles entre les caractères qui servent de repères ou encore constituent des balises de référence pour le formatage. 1. le constructeurwidget = Text(master, options) 2. les attributs2.1. liste des attributsautoseparators, background, bd, bg, blockcursor, borderwidth, cursor, endline, exportselection, fg, font, foreground, height, highlightbackground, highlightcolor, highlightthickness, inactiveselectbackground, insertbackground, insertborderwidth, insertofftime, insertontime, insertwidth, maxundo, padx, pady, relief, selectbackground, selectborderwidth, selectforeground, setgrid, spacing1, spacing2, spacing3, startline, state, tabs, tabstyle, takefocus, undo, width, wrap, xscrollcommand, yscrollcommand) 2.2. les attributs spécifiques attributs de dimensions : * height, width : les dimensions sont données en caractères et les valeurs en pixels sont donc conditionnées par la fonte de base. * spacing1 : espacement avant un bloc de texte ayant le tag de même nom. * spacing2 : espacement entre les lignes d'un un bloc de texte ayant le tag de même nom. * spacing3 : espacement à la fin d'un un bloc de texte ayant le tag de même nom. * wrap : indicateur de passage automatique à la ligne. Les trois valeurs possibles sont "char", "none" et "word" ; * tabs : valeurs de tabulation. Exemple : ("2c","5c","9c") définit les 3 premières tabulations à 2cm, 5cm, 9cm. Les tabulations suivantes se calculent par sauts de (9cm - 5cm), différences des deux dernières (éviter les espaces dans l'expression du tuple). * tabstyle : peut être "tabular" ou "wordprocessor". attributs de retour sur commande : * maxundo : mettre -1 pour un nombre illimité de possibilité de retour su commande (undo). Sinon, c'est le nombre de commandes autorisées pour le mécanisme undo. Zéro par défaut. * undo : à True, le mécanisme de retour sur commande est actif. False par défaut. * autoseparators : les séparateurs interviennent dans le mécanisme undo. Si l'attribut est True, attributs de curseur : * blockcursor : True ou False. True correspond à un curseur épais, False un curseur fin. * insertwidth : le curseur d'insertion est un rectangle dont on peut modifier la largeur (c'est 2 pixels par défaut). * insertbackground : le curseur d'insertion a une couleur, noire par défaut ; on peut changer cette couleur, valeur de l'attribut insertbackground. * insertborderwidth : par défaut, le rectangle du curseur d'insertion n'a pas de bordure. On peut lui un bordure avec le relief RAISED en posant la largeur de cette bordure. Cela n'est visible que si la largeur du rectangle du curseur est au moins deux fois la largeur de la bordure. * insertofftime : le curseur d'insertion clignote. L'attribut insertofftime donne en millisecondes le temps de disparition du rectangle. * insertontime : le curseur d'insertion clignote. L'attribut insertontime donne en millisecondes le temps ou le rectangle est visible. attribut de sélection automatique : * exportselection : par défaut, l'attribut est posé à True ; toute sélection passe automatiquement dans le presse-papier. Ce comportement par défaut est inhibé si on pose cet attribut à False. attribut d'état : * state : il y a deux états NORMAL="normal" et DISABLED="disabled" attributs de scroll : * xscrollcommand : s'il y a un ascenseur horizontal, permet de faire la liaison vers celui-ci. * yscrollcommand : s'il y a un ascenseur vertical, permet de faire la liaison vers celui-ci. exemple : valeurs par défaut. 'autoseparators': ('autoseparators', 'autoSeparators', 'AutoSeparators', 1, 1), 'background': ('background', 'background', 'Background', , '#ffffff'), 'bd': ('bd', '-borderwidth'), 'bg': ('bg', '-background'), 'blockcursor': ('blockcursor', 'blockCursor', 'BlockCursor', 0, 0), 'borderwidth': ('borderwidth', 'borderWidth', 'BorderWidth', , 1), 'cursor': ('cursor', 'cursor', 'Cursor', , 'xterm'), 'exportselection': ('exportselection', 'exportSelection', 'ExportSelection', 1, 1), 'fg': ('fg', '-foreground'), 'font': ('font', 'font', 'Font', , 'TkFixedFont'), 'foreground': ('foreground', 'foreground', 'Foreground', , '#000000'), 'height': ('height', 'height', 'Height', , 24), 'highlightbackground': ('highlightbackground', 'highlightBackground', 'HighlightBackground', , '#d9d9d9'), 'highlightcolor': ('highlightcolor', 'highlightColor', 'HighlightColor', , '#000000'), 'highlightthickness': ('highlightthickness', 'highlightThickness', 'HighlightThickness', , 1), 'inactiveselectbackground': ('inactiveselectbackground', 'inactiveSelectBackground', 'Foreground', , '#c3c3c3'), 'insertbackground': ('insertbackground', 'insertBackground', 'Foreground', , '#000000'), 'insertborderwidth': ('insertborderwidth', 'insertBorderWidth', 'BorderWidth', , 0), 'insertofftime': ('insertofftime', 'insertOffTime', 'OffTime', 300, 300), 'insertontime': ('insertontime', 'insertOnTime', 'OnTime', 600, 600), 'insertwidth': ('insertwidth', 'insertWidth', 'InsertWidth', , 2), 'maxundo': ('maxundo', 'maxUndo', 'MaxUndo', 0, 0), 'padx': ('padx', 'padX', 'Pad', , 1), 'pady': ('pady', 'padY', 'Pad', , 1), 'relief': ('relief', 'relief', 'Relief', , 'sunken'), 'selectbackground': ('selectbackground', 'selectBackground', 'Foreground', , '#c3c3c3'), 'selectborderwidth': ('selectborderwidth', 'selectBorderWidth', 'BorderWidth', , ), 'selectforeground': ('selectforeground', 'selectForeground', 'Background', , '#000000'), 'setgrid': ('setgrid', 'setGrid', 'SetGrid', 0, 0), 'spacing2': ('spacing2', 'spacing2', 'Spacing', '0', 0), 'spacing3': ('spacing3', 'spacing3', 'Spacing', '0', 0), 'startline': ('startline', '', '', '', ''), 'state': ('state', 'state', 'State', , 'normal'), 'tabs': ('tabs', 'tabs', 'Tabs', '', ''), 'tabstyle': ('tabstyle', 'tabStyle', 'TabStyle', , 'tabular'), 'takefocus': ('takefocus', 'takeFocus', 'TakeFocus', '', ''), 'undo': ('undo', 'undo', 'Undo', 0, 0), 'width': ('width', 'width', 'Width', 80, 80), 'wrap': ('wrap', 'wrap', 'Wrap', , 'char'), 'xscrollcommand': ('xscrollcommand', 'xScrollCommand', 'ScrollCommand', '', ''), 'yscrollcommand': ('yscrollcommand', 'yScrollCommand', 'ScrollCommand','', ''), 3. se repérer dans un texte3.1. les index de positionLe texte d'un widget Text est une séquence de caractères indexée : les caractères son numérotés à partir de 0. On peut également numéroter les lignes et les «colonnes». Les lignes sont numérotées à partir de 1 et les caractères sur une ligne, les colonnes, à partir de 0. Une position est calculée avant un caractère. Par exemple la colonne 1, colonne 0 est la position en début de texte. Pour caractériser une position on utilise une chaîne de caractères : * "" : lgn est le numéro de ligne, cln celui de la colonne. Par exemple "12.25" désigne la position en ligne 12, et avant un éventuel 25ème caractère. * "lgn.end" : end désigne la position juste avant le fin de ligne (retour de ligne ou fin de texte). Par exemple "" désigne la fin de la ligne 12. * INSERT = "insert" : "insert" désigne la position du curseur d'insertion. * CURRENT = "current" : "current" désigne la position la plus proche du curseur de la souris, bouton relâché. Si on déplace la souris bouton enfoncé, la mise à jour ne se fait pas. * END="end" : position après le dernier caractère du texte. * SEL_FIRST="sel.first" : position avant le premier caractère sélectionné. Il y a erreur si aucune sélection n'est faite. * "nom_de_marque" : position d'une marque dans le texte. * "tag.first" : position avant une région étiquetée(tag). * "tag.last" : position après une région étiquetée(tag). * "@x.y" : x et y sont des décimaux qui désignent les coordonnée d'un point dans le widget. La position est celle la plus proche du point de coordonnées données. * "objet_inclus" : Le widget inclus dans le texte peut être un widget ou une image. Dans ces cas, utiliser l'identificateur de l'instance du widget, ou le nom de celui de la PhotoImage ou de la BitmapImage (soit le nom donné automatiquement par tkinter, soit un nom donné par l'utilisateur, en prenant garde que c'est l'image affichée qui est nommée, -même en cas d'affichage multiple d'une même donnée-, et que tous les noms doivent être uniques). * "pos+n char" : pos est l'une des chaîne décrites ci-dessus ; n est un décimal : la chaîne décrit alors la position décalée de n caractères. Attention cependant, la position ne peut être supérieure à END. * "pos-n char" :la chaîne décrit la position décalée de n caractères vers l'avant. Attention cependant, la position ne peut être négative. Exemple : "12.5+5 char". L'espace peut être omis et char rempacé par c : "12.5+5c" peut s'avérer plus pratique. * "pos+n lines", "pos+n lines" : même chose avec des lignes. En principe, la position dans la ligne est conservé, sauf si la ligne est trop courte, auquel cas la position est la fin de la ligne. * "linestart" : position en début de ligne. Exemple : "current linestart". * "lineend" : position en fin de ligne. * "wordstart" : position avant le premier caractère du mot à la position spécifiée. Exemple : "12.5 wordstart" désigne la position avant le premier caractère du mot repéré en ligne 12, position 5. Le mot est formé de caractères alpha-numériques et du souligné (underscore). Il existe des marqueurs prédéfinies INSERT ou CURRENT. On les utilise partout où un marqueur est possible (saut la suppression de marqueur ! ). Il existe une propriété des marqueurs appelée la gravité (gravity). Elle peut être posée à LEFT ="left" ou RIGHT="right" et signifie qu'une insertion doit garder le marqueur respectivement à gauche ou à droite lors d'une insertion. Si on supprime un bloc, les marqueurs ne sont pas supprimées et se repositionnent dans le texte restant de manière naturelle. 4. les balises (tags)4.1. fonctionnalités et aspect de blocsLe widget Text donne la possibilité de régler la famille de caractères, la couleurs, la taille dans toute partie du texte. On peut aussi faire réagir le texte, les widgets inclus et les images incluses à une action de la souris ou du clavier. Pour contrôler ces apparences et fonctionnalités, on affecte à chacune par une balise (tag). Puis on associe ces balises sur chaque partie du texte concernée. (C'est un peu l'équivalent des balises en HTML). Un tag est un mot, sans espace, tabulation, point. Il existe une constante tag prédéfinie, SEL="sel" qui balise la partie du texte actuellement sélectionné, s'il y en a une ; dans ce cas tag_ranges(SEL) retourne un tuple non vide, alors qu'il est vide si le tag SEL n'est pas utilisé. 4.2. la pile des tagsLes parties taguées peuvent être imbriquées : par exemple un mot, inclus dans une phrase, inclus dans un paragraphe, tous trois tagués. En cas de conflit entre les tags, c'est le plus profond (ici, celui sur le mot) qui est pris en considération : les tags sont empilés par ordre d'apparition. 4.3. les option de tag
5. les méthodes5.1. utilitataires* compare(index1, op, index2) : retourne la valeur de la relation index1 op index2. op est la valeur d'opérateur d'une des chaînes suivantes: '<', '<=', '==', '>=', '>', où '!='. Exemple d'appel : compare ("12.0", "<", END) retourne True si la douzième ligne est avant la fin de texte. * index(index) : prend une valeur d'index entière et la retourne sous la forme "". 5.2. méthodes générales d'édition* insert (index, chars, *args) : insère la chaîne chars à gauche de l'index donné. Un tag peut être fourni comme troisième argument. On peut faire suivre d'une succession de chaînes et tags. * edit_modified(arg=None) : le drapeau booléen modified flag est une propriété interne accessible par la présente méthode. Si une modification se produit dans le texte, le drapeau est posé à True. La méthode retourne l'état actuel du drapeau en le forçant suivant le valeur booléenne donnée à arg. * edit_redo() : rétablit la dernière annulation si l'attribut undo est posé à True. Il y a erreur si la pile d'annulation est vide. Ne fait rien si l'attribut undo est posé à False. * edit_reset() : vide la pile d'annulation. * edit_separator() : insère un repère dans la pile d'annulation si l'attribut undo est posé à True. Ne fait rien sinon. * edit_undo () : annule la dernière «action d'édition » sur le texte si l'attribut undo est posé à True, ne fait rien sinon. Un action d'édition se définit comme toute commande d'insertion ou d'effacement enregistrée sur la pile d'annulation entre deux repères séparateurs. Il y a erreur si la pile est vide. * get (index1, index2=None): retourne le texte compris entre les positions index1 et index2. Si index2 n'est pas donné, un seul caractère est retourné. * dump(index1, index2=None, command=None, options) : retourne le contenu du widget entre index1 et index2 Le type de contenu retourné est filtré en suivant les paramètre à mots clefs optionnels. Si des paramètres de mot clefs all, image, mark, tag, text, ou window sont posés à True, alors les items correspondants sont retournés. Le résultat est un liste de triplets de la forme (clef, valeur, index). Par défaut, c'est all qui est posé à True. Si l'argument 'command' est donné, la fonction est appelée pour chaque pour chaque élément de la liste de triplets, les valeurs de chaque triple servant d'argument à la fonction. Dans ce cas la liste n'est pas retournée. Pour imprimer, on utilise get() et dump(), à envoyer à une sortie adapté ; par exemple le module PSDraw de PIL. * mark_names() : la méthode retourne tous les noms de marqueurs. * mark_set(markName, index) : pose un marqueur markName avant le caractère à la position index. * mark_unset(*markNames) : efface tous les marqueurs de la séquence marknames. * mark_next(index) : retourne le nom du premier marqueur après index. * mark_previous(index) : retourne le nom du premier marqueur avant index. 5.4. méthodes pour les éléments fenêtrés inclus* window_cget (index, option) : c'est l'habituel cget(), mais sur un élément fenêtré inclus, trouvé à la position index. * window_configure(index, options), window_configure(index, options) : c'est l'habituel configure(), mais sur un élément fenêtré inclus, trouvé à la position index. * window_names() : retourne une séquence de tous les noms d'éléments fenêtrés inclus. * window_create(index, option) : crée un élément fenêtré à la position index, avec les options spécifiées. Il y a deux façons d'inclure un widget dans le widget Text, par les options create ou window. Les options possibles sont :
5.5. méthodes pour les images incluses les options d'image sont :
* image_cget(index, clef_option) : retourne la valeur de clef_option pour une image incluse à la position index. * image_configure(index, options), image_configure(index, options) : configure l'image incluse à la position index. * image_create( index, options) : inclut une image à la position index, comme un caractère qui aurait la taille de l'image. * image_names() : retourne les noms de toutes les images incluses sous forme d'un tuple. 5.6. méthodes pour les balises* tag_add(tagName, index1, index2=None, *args) : ajoute un tag , nommé tagName, sur le bloc compris entre index1 et index2 Si index2 est omis, un seul caractère est tagué. On peut faire suivre d'autant de paires semblables. * tag_unbind (tagName, sequence, funcid=None) : délie le bloc tagué par tagName, pour l'événement de séquence sequence, et de gestionnaire funcid. Si funcid n'est pas spécifié, tous les gestionnaires sont déliés de du bloc pour l'événement. * tag_bind (tagName, sequence, func, add=None): fait une liaison entre le bloc nommé tagName, avec un événement de séquence sequence, de gestionnaire func. add est traditionnel pour les liaisons d'événement : add=True ajoute la liaison à celles qui existent déjà ; False force le remplacement. * tag_cget (tagName, clef_option) : retourne la valeur d'attribut du mot clef clef_option pour le tag nommé tagName. * tag_configure (tagName, options), tag_config( tagName,options) : configure le tag nommé tagName. * tag_delete (*tagNames) : supprime tous les tags de la liste d'arguments. * tag_names(index=None) : retourne une liste des tags valides pour l'index. Les retourne tous si l'index n'est pas précisé. * tag_nextrange(tagName, index1, index2=None) : index2 est supposé supérieur à index1 (le fin du texte pour index2=None). La méthode recherche en commençant à index1 et jusque index2 si tagName est le nom d'un tag. Si elle ne trouve rien, elle retourne une chaîne vide. Si elle rencontre une position de début de tag d, elle cherche la position f de fin correspondante. Et elle retourne [l,f]. * tag_prevrange(tagName, index1, index2=None) : même chose, mais avec index2 inférieur à index1 (début du texte si index2=None) ; la recherche est fait en remontant dans le texte. * tag_raise(tagName, aboveThis=None) : change la priorité du tag, qui se place en dessus de celui nommé aboveThis. Si le second paramètre est None, le tag a une priorité absolue. * tag_ranges(tagName) : retourne une liste formée des positions de début et de fin de tous les blocs de texte ayant le tag nommé tagName. La liste a l'allure suivante : [d0, f0, d1, f1, .dn, fn] * tag_remove (tagName, index1, index2=None) : enlève les tags entre index1 et index2. Si index2 est omis, seul le tag en index1 est enlevé. Attention, les tags en tant que tels ne ont pas supprimés, même si on les enlève tous (tag_remove(tagName, "1.0", END)). 5.7. méthode de rendu* dlineinfo(index) : retourne le tuple (x,y,width,height,baseline) donnant la boite englobante et la position de la ligne de base (baseline) de la partie visible de la ligne contenant le caractère après index. * bbox(*args) : retourne un tuple (x,y,width,height) qui donne les bornes de la boite de la partie visible pour chaque caractère dont l'index est dans args. Attention au retards à l'affichage (dans ce cas, faire update_idletasks()). - pattern = motif recherché (chaîne) ; - index = position du début de recherche ; - stopindex = position de fin de recherche ; - forward : en avant (booléen) ; - backward : en arrière (booléen) ; - exact : recherche d'une concordance exacte avec le motif (booléen) ; - regexp = expression régulière (booléen) ; le motif est à considérer comme une expression régulière ; seul un sous ensemble des possibilités des regexp de Python est permise. Sont reconnus : le point . ; les répétiteurs + * ? ; la suite de caractère [xyz..], le parenthésage (…) ; l'alternative e1|e2 - nocase = ne pas tenir compte de la casse (booléen) ; - count = variable de contrôle de type IntVar ; le variable prend la valeur de longueur de la chaîne identifiée (interroger la variable par la méthode get()). - elide = (booléen). retourne l'index du premier caractère de la chaîne identifiée, ou sinon une chaîne vide (la longueur se trouve par v.get() où v est la variable associée à count). 5.9. méthodes pour les ascenseurs* scan_mark(x, y) : sert dans le scrolling rapide par glissement de la souris. Si on presse le bouton de la souris en un point et qu'on la déplace ensuite, puis qu'on relâche, la souris se déplace dans la direction du mouvement en proportion de la distance parcourue. Pour mettre en œuvre le procédé, associer l'événement «presser de bouton souris» ("<ButtonPress") à un gestionnaire qui appelle scan_mark(x, y) à la positon (x,y) de la souris, et l'événement «déplacer le souris» ("") à un gestionnaire qui appelle scan_dragto(x, y), avec (x, y) comme position actuelle de la souris. * scan_dragto(x, y) : ajuste un déplacement de l'affichage du texte à 10 fois la différence entre x et y et les coordonnées données dans scan_mark. * see(index) : scrolle pour rendre visible le caractère à la position index. Remplace yview_pickplace(), obsolète. méthodes héritées : * xview(*arg) : recherche et change la position horizontale de la vue. Voir les méthodes qui suivent. * xview_moveto(fraction) : c'est la même chose que xview(MOVETO, fraction). Cette méthode est destinée au widget de scroll horizontal. Elle déplace la vue sur le texte du widget à la position définie par fraction. fraction = 0.0 correspond à la gauche, et fraction = 1.0 est l’extrême droite. * xview_scroll (n, units) : même chose que xview(SCROLL, n, what). Déplace la vue sur le texte vers la gauche ou la droite. n, entier relatif donne l'ampleur du déplacement (positif : à droite et négatif : à gauche) et units donne le genre de déplacement qui peut être UNITS (caractères) ou PAGES (pages). * yview(*arg), yview_moveto(fraction), yview_scroll (n, units) : semblables aux précédentes, mais dans le sens vertical. 6. quelques exemples6.1. méthodes de sélectionIl n'y a rien de spécifique dans le widget Text en ce qui concerne la sélection, autre que le tag SEL, et l'initialisation de SEL_FIRST et SEL_LAST lorsque la sélection existe. Une utilisation abusive de ces constantes provoque une erreur. Voici quelques procédés utiles : effacer la sélection courante : defeffacer_sel (widget_Text) : # il s'agit d'un widget Text widget_Text.tag_remove (SEL, "1.0", END) sélectionner defcreer_sel (widget_Text, index1, index2) : widget_Text.tag_remove (SEL, "1.0", index1) widget_Text.tag_add (SEL, index1, index2) widget_Text.tag_remove (SEL, index2, END) sélection présente defexiste_sel (widget_Text) : return bool(widget_Text.tag_range(SET)) 6.2. un exemple simpleLe script comporte deux widgets Text. Le widget source permet d'éditer du texte et de sélectionner un bloc. Les deux commandes permettent de copier le texte sélectionné ou tout le texte dans le widget cible, à la position «actuelle» du curseur.
Résultat : tk21 : CanvasUn widget Canvas (un canevas) est un élément fenêtré destiné à recevoir des éléments graphiques «dessinés». On peut dessiner des traits, des surfaces, des textes, des images. Chaque élément dessiné est supporté par un calque transparent ; les calques sont superposés dans l'ordre où ils sont dessinés, et les parties opacifiées cachent donc tout ce qui est en-dessous. L'ordre des calques peut être modifié, et chaque calque peut être manipulé indépendamment de tous les autres. Mais on peut également les regrouper par familles (voit tags). Pour manipuler les calques, les images qu'ils supportent sont identifiés. Le Canvas ressemble à un logiciel d'édition graphique vectoriel où les transformations sont recalculées à partir des directives de création. 1. le constructeurwidget = Canvas (master, options). * arc : ellipse, segment ou partie angulaire d'une ellipse ; l'ellipse est repérée par 4 valeurs : coin supérieur gauche (x1, y1) et coin inférieur droit (x2, y2) du rectangle enveloppant l'ellipse. * bitmap : le bitmap est repéré par son coin supérieur droit. * image : l'image est repérée par son coin supérieur droit. * ligne : il s'agit d'une ligne polygonale, repérée par la succession de ses sommets. * oval : il s'agit d'une ellipse d'axes parallèles aux bords du canevas, avec le cercle comme cas particulier. Voir arc. * polygon : c'est une ligne polygonale fermée. * rectangle : un rectangle de côtés parallèles aux bords du canevas, avec le carré comme cas particulier. * text : on peut dessiner du texte sur un canevas, avec le choix de la fonte, de la taille etc. * window : on peut créer une «réserve» rectangulaire, où on peut placer un widget, par exemple un cadre (Frame) et toute construction interne dans le cadre que l'on veut. 2. les attributs2.1. liste des attributsbackground, bd, bg, borderwidth, closeenough, confine, cursor, height, highlightbackground, highlightcolor, highlightthickness, insertbackground, insertborderwidth, insertofftime, insertontime, insertwidth, offset, relief, scrollregion, selectbackground, selectborderwidth, selectforeground, state, takefocus, width, xscrollcommand, xscrollincrement, yscrollcommand, yscrollincrement 2.2. les attributs spécifiques* closeenough : fixe à quelle distance le curseur de la souris doit être d'un item pour être considéré comme à l'intérieur. * confine : booléen. Posé à True,valeur par défaut, le scrolling est confiné à la région définie dans scrollregion. * xscrollincrement : posé à 0, le scrolling est assez continu ; si on donne une valeur entière positive, le scrolling se positionne uniquement aux multiples de l'attribut. En particulier, une action sur les flèches de la barre de scroll horizontal fait sauter l'affichage, avec un pas égal à l'attribut. * yscrollincrement : même chose, mais vertical. * yscrollcommand : on peut ajouter un ascenseur vertical au widget pour manipuler une saisie plus large que celle autorisée par la fenêtre de saisie. Voir le chapitre tk12. * xscrollcommand : on peut ajouter un ascenseur horizontal au widget pour manipuler une saisie plus large que celle autorisée par la fenêtre de saisie. 'background': ('background', 'background', 'Background', '#d9d9d9', 'white'), 'bd': ('bd', 'borderWidth'), 'bg': ('bg', 'background'), 'borderwidth': ('borderwidth', 'borderWidth', 'BorderWidth', '0', '0'), 'closeenough': ('closeenough', 'closeEnough', 'CloseEnough', '1', '1.0'), 'confine': ('confine', 'confine', 'Confine', '1', '1'), 'cursor': ('cursor', 'cursor', 'Cursor', '', ''), 'height': ('height', 'height', 'Height', '7c', '600'), 'highlightbackground': ('highlightbackground', 'highlightBackground', 'HighlightBackground', '#d9d9d9', '#d9d9d9'), 'highlightcolor': ('highlightcolor', 'highlightColor', 'HighlightColor', '#000000', '#000000'), 'highlightthickness': ('highlightthickness', 'highlightThickness', 'HighlightThickness', '1', '1'), 'insertbackground': ('insertbackground', 'insertBackground', 'Foreground', '#000000', '#000000'), 'insertborderwidth': ('insertborderwidth', 'insertBorderWidth', 'BorderWidth', '0', '0'), 'insertofftime': ('insertofftime', 'insertOffTime', 'OffTime', '300', '300'), 'insertontime': ('insertontime', 'insertOnTime', 'OnTime', '600', '600'), 'offset': ('offset', 'offset', 'Offset', '0,0', '0,0'), 'relief': ('relief', 'relief', 'Relief', 'flat', 'flat'), 'scrollregion': ('scrollregion', 'scrollRegion', 'ScrollRegion', '', ''), 'selectbackground': ('selectbackground', 'selectBackground', 'Foreground', '#c3c3c3', '#c3c3c3'), 'selectborderwidth': ('selectborderwidth', 'selectBorderWidth', 'BorderWidth', '1', '1'), 'selectforeground': ('selectforeground', 'selectForeground', 'Background', '#000000', '#000000'), 'state': ('state', 'state', 'State', 'normal', 'normal'), 'takefocus': ('takefocus', 'takeFocus', 'TakeFocus', '', ''), 'width': ('width', 'width', 'Width', '10c', '800'), 'xscrollcommand': ('xscrollcommand', 'xScrollCommand', 'ScrollCommand', '', ''), 'xscrollincrement': ('xscrollincrement', 'xScrollIncrement', 'ScrollIncrement', '0', '0'), 'yscrollcommand': ('yscrollcommand', 'yScrollCommand', 'ScrollCommand', '', ''), 'yscrollincrement': ('yscrollincrement', 'yScrollIncrement', 'ScrollIncrement', '0', '0') 3. fonctionnement du widget3.1. dimensions* les dimensions du widget sont celles de la fenêtre d'affichage, pas la surface où il est possible decréer les calques pour dessiner. Ceux-ci sont supposés indéfinis. * la dimension d'affichage de la vue, c'est à dire ce que l'on peut amener à être vu dans la fenêtred'affichage, est fixé par l'attribut scrollregion. Les ascenseurs sont un passage quasi obligé pour afficher ce qui déborde de l'élément fenêtré Canvas (on pourrait imaginer un déplacement de la vue par les touches du clavier, ou par manipulation de la molette de la souris ). Cet attribut est actif si confine est posé à True, ce qui est le cas par défaut. Si l'attribut scrollregion n'est pas défini (chaîne vide), on ne peut se servir que des flèches de la barre de scroll. Mais, les calques qui portent les graphismes dessinés peuvent évoluer lors du scrolling. Il existe donc un second système de coordonnées qui au départ coïncide avec le premier, mais lié à la vue et qui suit ses déplacements. C'est dans ce système que s'effectue le placement des items graphiques. exemple de canevas avec ascenseurs :
résultat : 3.3. identification et taguage des items* Lors de la création d'un élément graphique, la méthode de définition de l'instance (item) retourne unnuméro (entier),. Ce numéro est unique est suffit à identifier l'item et on ne peut le changer. On peut utiliser indifféremment cet identificateur dans les méthodes comme entier n ou comme la chaîne décimale str(n). Un tag est une chaîne de caractères sans espace intérieur. On recommande cependant d'user des modes habituels d'identification, d'éviter les accents par exemple, ou d'utiliser des mots faits uniquement de chiffres. On peut marquer d'un même tag plusieurs items : il appartiennent alors au même groupe de tag ; mais rien n'interdit qu'un item soit multitagué. La seule limitation pour un tag est d'être lié à au moins un item. * On peut avoir besoin de désigner tous les items ; la constante ALL="all" permet cette désignation. * De même, on peut désigner l'item «sous» la souris par la constante CURRENT="current". Une disposition pratique : beaucoup de méthodes confondent tag et id, c'est-à-dire admettent les id comme des tags ordinaires. Dans ce cas, les paramètres impliqués seront appelés tagOrId comme le fait la documentation officielle. Si on est dans le cas où on a utilisé un tag désignant plusieurs items, c'est sauf stipulation contraire, celui de plus bas niveau qui est pris. 4. méthodes générales du widget CanvasOn réserve la création des items graphiques à la section suivante create, où chacune fera l'objet d'une étude particulière. 4.1. méthodes générales* delete (tagOrId) : supprime tous les items désignés par tagOrId. Il n'y a pas d'erreur s'il n'y en a aucun. * itemcget(tagOrId, option) : retourne la valeur d'option correspondant à la chaîne option pour l'item défini par tagOrId. * itemconfigure (tagOrId, options) : c'est la méthode configure des widgets, adaptée aux items. Les valeurs des mots clefs sont définis dans la section create. * itemconfig tagOrId, options) : même chose que le précédent. * type(tagOrId) : retourne le type de l'item désigné par tagOrId. * postscript( options) : imprime le contenu du canevas dans un "fichier" postscript. Les options sont les suivantes :
il existe d'autres items, non documentés : colormap, fontmap, pageanchor, pageheight, pagewidth, pagex, pagey, 4.2. méthodes de manipulation de tags* addtag_above(newtag, tagOrId) : ajoute le tag newtag à l'item juste au-dessus de celui (au sens des calques empilés) marqué par tagOrId. * addtag_all(newtag) : ajoute le tag newtag à tous les items existants. * addtag_below(newtag, tagOrId) : comme addtag_above(), mais au-dessous. * addtag_closest(newtag, x, y, halo=None, start=None) : recherche la bordure d'un item graphique qui est la plus proche du point de coordonnées calques (x, y) ; puis lui applique le tag newtag. S'il y a ambiguïté, c'est le plus haut dans l'empilement qui est pris. Le paramètre halo est un entier : il permet de "grossir" le point d'identification ; halo=5 recherche jusqu'à 5 pixels de (x,y). Si start est un identificateur d'item, la tag est appliqué à tous les items d'identificateur supérieur. * addtag_enclosed(newtag, x1, y1, x2, y2) : applique le tag newtag à tous les items inclus dans le rectangle (x1, y1, x2, y2). * addtag_overlapping(newtag, x1, y1, x2, y2) : même chose que addtag_enclosed(), mais en prenant tous les items qui ont au moins un point commun avec le rectangle. * addtag_withtag(newtag, tagOrId) : affecte le tag newtag à tout item qui a le tag ou l'identificateur tagOrId. * dtag (tagOrId, dTag) : enlève le tag dTag aux items qui l'auraient dans ceux désignés par tagOrId. 4.3. méthodes relatives aux dimensions et aux transformations* bbox(*args) : retourne un tuple (x1, y1, x2, y2) définissant un rectangle qui englobe tous les items de tag appartenant à la suite donnée en paramètre. Pour obtenir la boite qui inclut tous les items, par exemple pour régler les ascenseurs,faire bbox(ALL). * canvasx(screenx, gridspacing=None), canvasy(screeny, gridspacing=None) : (screenx, screeny) sont les coordonnées d'un pointM dans le repère fixe lié à la fenêtre. Les deux méthodes renvoient les coordonnées x ou y de ce point M dans le repère lié aux calques. Si gridspacing (entier positif) est donné, le résultat est un multiple de cette valeur. * coords(tagOrId) : retourne les coordonnées dans le repère lié au calques de l'item désigné par tagOrId (s'il y a plusieurs items, prend le plus bas). Les coordonnées sont rendues dans un tupple de flottants, avec 2 ou 4 éléments suivant les items (Voir la section create). * coords (tagOrId, x0, y0, x1, y1 ) : prend l'item le plus bas défini par tagOrId et lui impose le système de coordonnées qui suit, selon le mode utilisé pour son create. idImage = leCanevas.create_image(50, 50, image=pythonImage, anchor="nw") leCanevas.coords(idImage, 200, 200)) * tag_lower (tagOrId, id) : descend les items définis par tagOrId en-dessous de celui défini par id. * tag_raise (tagOrId, id) : comme tag_lower mais au-dessus. * move (tagOrId, deltaX, deltaY) : déplace en bloc les items définis par tagOrId en ajoutant deltaX et deltaY à leurs coordonnées. Les ascenseurs ne sont pas synchronisés. * scale (tagOrId, offsetX, offsetY, ratioX, ratioY) : applique à tous les items désignés par tagOrId la transformation suivantes : Tout point M de coordonnées (x,y) est remplacé par M'( offsetX + ratioX*(x - OffsetX), offsetY + ratioY*(Y - OffsetY) ). * tag_bind( tagOrId, sequence=None, func=None, add=None) : lie (bind) tous les items possédant le tag tagOrId pour l'événement défini par sequence et le gestionnaire func. Voir le chapitre 7 sur les événements. 4.5. méthodes de texte* dchars (tagOrId, first=0, last=first) :efface des caractères aux items textuels de tagOrId. Commence au caractère d'ordre first, et inclut le caractère last. Le second argument peut être END="end". * focus(tagOrId=None) : donne le focus au premier item focusable désigné par tagOrId. Avec l'argument None, retourne l'item qui a le focus ou une chaîne vide. * icursor (tagOrId, index) : si l'item désigné a le focus, positionne le curseur d'insertion à la position index. END="end" est admis. * index (tagOrId, specificateur) : retourne la position du curseur pour l'item spécifié par tagOrId (le plus bas s'il y en a plusieurs). Le spécificateur peut être : INSERT, END, SEL_FIRST, SEL_LAST, "@x, y" Voir le widget Text pour la signification. * insert (tagOrId, index, texte) : insertion d'une chaîne définie par texte, à la position définie. On peut utiliser les spécificateurs INSERT, END, SEL_FIRST, SEL_LAST. * select_adjust (tagOrId, index) : ajuste la fin de la sélection au plus près de l'index pour l'item tagOrId. * select_clear () : enlève la sélection si elle est sur le widget Canvas. * select_from(tagOrId, index) : pose un début de sélection. * select_item() : retourne l'item qui a le focus. * select_to(tagOrId, index): pose un fin de sélection. 4.5. méthodes de recherche d'item* find_above (tagOrId) : retourne l'id de l'objet au-dessus de l'item le plus haut désigné par tagOrId s'il existe. Retourne un singleton ou un tuple vide. * find_all() : retourne un tupple des id de tous les items. * find_below(tagOrId) : semblable à find_above(), mais au-dessous. * find_enclosed(x1, y1, x2, y2) : retourne un tuple des id des items contenus dans le rectangle défini par x1, y1, x2, y2). * find_overlapping x1, y1, x2, y2) : même chose avec les items qui ont au moins un point commun avec le rectangle. * find_withtag(tagOrId) ; retourne un tupple des items qui partagent le tag tagOrId. 4.6. méthodes de scroll* scan_mark( x, y) : pour cette méthode et la suivante on renvoie vers le widget Entry. * scan_dragto(x, y, gain=10) : id. * xview(), yview() : les méthodes xview() et yview() sont à usages multiples. - utilisées sans argument, elle retournent un tuple deflottants. Pour xview(), le premier nombre donne le rapport de la partie gauche cachée à la largeur totale, et le second, prend la somme de la largeur cachée à gauche et la largeur de la partie visible et divise par a largeur totale : c'est exactement l'argument de set() pour la barre de scroll horizontale. C'est la même chose pour yview(), mais dans le sens vertical. Ces méthodes fournissent aux barres de scroll les renseignement pour leur réglage. - les arguments peuvent être deux ; "moveto", nombre flottant. Dans ce cas, la vue est modifiée et décalée en proportion de l'arguent flottant (valeur qui est donc entre -1 et +1. C'est ce que fait la barre de scroll quand on déplace le curseur avec la souris. - les arguments peuvent être trois : "scroll", compte, "units". Le paramètre compte peut être un entier +1 ou -1. Dans ce cas, la vue est modifiée par déplacement d'un nombre de pixels défini dans xscrollincrement ou yscrollincrement. C'est ce que fait la barre de scroll quand on clique les flèches ou la gouttière. Si compte est un entier de valeur absolue supérieure 1, le déplacement est multiplié par cette valeur. Voir l'exemple donné en section 3. 5. les méthodes create. 5.1. création à partir d'un Bitmap ou d'une Image les méthodes : x et y sont les coordonnées du centre de l'image, sauf option contraire. id est l'identificateur qui sera utilisé pour manipuler l'item. les options :
pour une Image : 'activeimage': ('activeimage', '', '', '', '') 'anchor': ('anchor', '', '', 'center', 'nw'), 'disabledimage': ('disabledimage', '', '', '', ''), 'image': ('image', '', '', '', 'pyimage1'), 'state': ('state', '', '', '', ''), 'tags': ('tags', '', '', '', ''), 5.2. création de ligne et polygone les méthodes : id = widget_canvas.create_line (x0, y0, x1, y1, , xn, yn, options) id = widget_canvas.create_polygon (x0, y, x1, y1,., xn, yn, options) les options pour create_line : * dash : par défaut on a une ligne droite continue ; l'attribut dash permet de faire un pointillé ou un motif plus complexe. La valeur est un tuple d'entiers qui décrit un motif : les valeurs d'index impair donnent les pixels colorés, ceux d'index impair les pixelss transparents. Par exemple (5,5,20,5) donne le motif point trait. Si on n'a qu'une valeur, les pixels colorés et les pixels transparents sont de même longueur. * dashoffset : la valeur est un entier n ; pour tracer en pointillé, on commence au nème pixel du motif. * fill : couleur du trait * stipple : permet de dessiner avec un bitmap. * width : épaisseur du trait * arrowshape : prend un tuple d'entiers (d1, d2, d3) qui définissent la flèche. * capstyle : forme de fin de ligne. Kes valeurs sont BUTT="butt", PROJECTING="projecting, ROUND="round" * joinstyle : forme du raccord entre segments. Les valeurs sont ROUND="round", BEVEL="bevel" et MITTER="mitter". * offset :si on utilise un bitmap pour tracer une ligne, permet d'assurer la continuité des raccords entre les répétitions du bitmap. La valeur peut être : - une chaîne contenant deux valeurs séparées par une virgule "x,y" ; x et y désignent un décalage, en pixels pour passer d'un bitmap au suivant. - "#x,y" : décale le bitmap de motif par rapport à la fenêtre du canevas - une ancre : N="n", S="s", E="e", W="w", NE="ne", SE="se", SW="sw", NW="nw", CENTER="center" ; ancre le bitmap. Par exemple E="e" fait coïncider le centre du bitmap et le milieu du côté gauche du rectangle enveloppant la ligne. NE="ne" fait coïncider les coins haut/gauche. * smooth : c'est un booléen. Avec smooth à True, la ligne est dessinée comme une 2-spline (spline parabolique). Sinon, la ligne est calculée comme ligne droite. * splinesteps : donne le pas de calcul si smooth est posé à True. 'activedash': ('activedash', '', '', '', ''), 'activefill': ('activefill', '', '', '', ''), 'activestipple': ('activestipple', '', '', '', ''), 'activewidth': ('activewidth', '', '', '0.0', '0.0'), 'arrow': ('arrow', '', '', 'none', 'last') 'arrowshape': ('arrowshape', '', '', ('8', '10', '3'), ('16', '30', '10')), 'capstyle': ('capstyle', '', '', 'butt', 'butt'), 'dash': ('dash', '', '', '', ''), 'dashoffset': ('dashoffset', '', '', '0', '0'), 'disableddash': ('disableddash', '', '', '', ''), 'disabledfill': ('disabledfill', '', '', '', ''), 'disabledstipple': ('disabledstipple', '', '', '', ''), 'disabledwidth': ('disabledwidth', '', '', '0.0', '0.0'), 'fill': ('fill', '', '', 'black', 'red'), 'joinstyle': ('joinstyle', '', '', 'round', 'round'), 'smooth': ('smooth', '', '', '0', '0'), 'splinesteps': ('splinesteps', '', '', '12', '12'), 'state': ('state', '', '', '', ''), 'stipple': ('stipple', '', '', '', ''), 'tags': ('tags', '', '', '', 'monGroupe'), 'width': ('width', '', '', '1.0', '3.0'), les options pour create_polygon : Quelques particularités concernent les items polygones. * fill : concerne cette fois la surface du polygone. La transparence s'obtient par fill="". * outline :couleur de la frontière. Tous les attributs contenant outline sont relatifs à la frontière. * width : largeur de la frontière. * offset : concerne la surface et non la frontière, pour laquelle il faut faire outlineoffset. 'activedash': ('activedash', '', '', '', ''), 'activefill': ('activefill', '', '', '', ''), 'activeoutline': ('activeoutline', '', '', '', ''), 'activeoutlinestipple': ('activeoutlinestipple', '', '', '', ''), 'activestipple': ('activestipple', '', '', '', ''), 'activewidth': ('activewidth', '', '', '0.0', '0.0'), 'dash': ('dash', '', '', '', ''), 'dashoffset': ('dashoffset', '', '', '0', '0'), 'disableddash': ('disableddash', '', '', '', ''), 'disabledfill': ('disabledfill', '', '', '', ''), 'disabledoutline': ('disabledoutline', '', '', '', ''), 'disabledoutlinestipple': ('disabledoutlinestipple', '', '', '', ''), 'disabledstipple': ('disabledstipple', '', '', '', ''), 'disabledwidth': ('disabledwidth', '', '', '0.0', '0.0'), 'fill': ('fill', '', '', 'black', 'red'), 'joinstyle': ('joinstyle', '', '', 'round', 'round'), 'offset': ('offset', '', '', '0,0', '0,0'), 'outline': ('outline', '', '', '', ''), 'outlineoffset': ('outlineoffset', '', '', '0,0', '0,0'), 'outlinestipple': ('outlinestipple', '', '', '', ''), 'smooth': ('smooth', '', '', '0', '0') 'splinesteps': ('splinesteps', '', '', '12', '12'), 'state': ('state', '', '', '', ''), 'stipple': ('stipple', '', '', '', ''), 'tags': ('tags', '', '', '', ''), 'width': ('width', '', '', '1.0', '3.0'), id = widget_canvas.create_rectangle (x0, y0, x1, y1, options) id = widget_canvas.create_oval (x0, y0, x1, y1, options) attributs : Ce sont ceux des polygones. 5.4. création d'un arc la méthode : id = create_arc (x0, y0, x1, y1, options) Un arc est une partie d'ellipse. Le rectangle enveloppant est celui de l'ellipse qui est découpée. Tous les attributs valides pour les polygones s'appliquent. les attributs relatifs à la section : * start : pour définir un item arc, on repère d'abord l'angle (en degrés) fait avec l'axe horizontal du segment joignant le centre C de l'ellipse et le point de départ D sur l'arc. * extent : le point d'arrivée est le point F : on définit l'angle que fait CD et CF. On compte dans le des aiguilles d'une montre. * style : le style dit comment faire la découpe. Il y a trois styles : - PIESLICE="pieslice" : découpage en part de tarte. - ARC="arc" : seul l'arc subsiste ; il n'y a pas de remplissage - CHORD="chord" : la portion est limitée par la corde de l'arc. 'extent': ('extent', '', '', '90', '90.0'), 'start': ('start', '', '', '0', '0.0'), 'style': ('style', '', '', '', 'pieslice') 5.5. création de texte la méthode : id = widget_canvas.create_text (x, y, options) L'item texte est toujours horizontal. Cela devrait changer avec la version 8.6 de Tcl/Tk. Il est focusable, possède un curseur et autorise les affichages et même la saisie au prix de quelques acrobaties. Les méthodes qui interagissent avec l'item ont été signalées dans la section 4. Pour récupérer un texte utiliser cget(id, "text") où id est l'identificateur de l'item. Pour le changer, itemconfig (id, text=nouveau_texte). les attributs de l'item Text : * fill : se rapporte à la couleur des caractères. * anchor : le placement se fait relativement au centre de l'item. Utiliser les ancres classiques : N="n", S="s", E="e", W="w", NE="ne", SE="se", SW="sw", NW="nw", CENTER="center". * justify : les valeurs sont : LEFT="left", RIGHT="right", CENTER="center". Cet attribut prend son sens si le texte est multiligne. * underline : ajoute un souligné. * text : texte qui est affiché dans l'item. * width : en principe, le texte d'une ligne n'est pas limité en longueur. Cependant, on peut spécifier une largeur maximale. Mais dans ce cas, les mots risquent d'être tronqués. Il n'y a pas de wrap sur les mots comme avec le widget Text. 'activefill': ('activefill', '', '', '', ''), 'activestipple': ('activestipple', '', '', '', ''), 'anchor': ('anchor', '', '', 'center', 'center'), 'disabledfill': ('disabledfill', '', '', '', ''), 'disabledstipple': ('disabledstipple', '', '', '', ''), 'fill': ('fill', '', '', 'black', 'red') 'font': ('font', '', '', 'TkDefaultFont', ('Helvetica', '-25')), 'justify': ('justify', '', '', 'left', 'left'), 'offset': ('offset', '', '', '0,0', '0,0'), 'state': ('state', '', '', '', 'disabled'), 'stipple': ('stipple', '', '', '', ''), 'tags': ('tags', '', '', '', ''), 'text': ('text', '', '', '', '?'), 'underline': ('underline', '', '', '-1', '-1'), 'width': ('width', '', '', '0', '0'), 5.6. création de fenêtre la méthode : id = widget_canvas.create_window(x, y, options ) Dans une fenêtre, on peut placer un widget quelconque. Ce widget doit être un descendant de la même fenêtre de haut niveau que le canevas. On peut mettre un cadre (Frame) dans la fenêtre et traiter ce cadre de la même façon que n'importe quel cadre dans l'application. les options de l'item : * anchor : le placement se fait relativement au centre de l'item. Utiliser les ancres classiques : N="n", S="s", E="e", W="w", NE="ne", SE="se", SW="sw", NW="nw", CENTER="center". * height, width : espace réservé pour le widget inclus. Par défaut, la fenêtre épouse le widget. * window : le widget inclus. 'anchor': ('anchor', '', '', 'center', 'center') 'height': ('height', '', '', '0', '0'), 'tags': ('tags', '', '', '', ''), 'width': ('width', '', '', '0', '0'), 'window': ('window', '', '', '', '.21717584.21718608'), tk22 : ScaleUn widget Scale est un sélecteur à curseur glissant (slider) sur une échelle numérique (entier ou flottant). Il peut être vertical ou horizontal. Le slider est focusable et peut être commandé par les touches fléchées (fg, fd, fh, fb) du clavier si le widget a le focus. 1. le constructeursyntaxe widget = Scale (conteneur, options) exemple :
scaleVert =Scale(racine, font=maFonte, width=25, length=200, from_=20, to=0, sliderrelief=GROOVE, bigincrement=10, resolution=2, activebackground="red", highlightcolor="red", relief="solid") (row=0, rowspan=2, column=1, padx=10, pady=10) racine.mainloop() # fichier : tk22ex00 résultat : 2.2. les attributs spécifiques* activebackground : couleur du slider lorsque le souris l'active en le survolant. * bigincrement : incrément lorsque le widget a le focus et que l'on fait Ctrl-fg, Ctrl-fd etc. * command : la valeur est un fonction qui prend un argument, et l'affecte à la valeur de l'échelle. Ce gestionnaire est appelé à chaque déplacement du slider. En cas de déplacement rapide du slider, le gestionnaire n'est appelé que lorsque le slider s'immobilise. * digits : la valeur courante du widget est contrôlée par l'attribut variable. Si c'est une StringVar, digit définit combien de chiffres seront retenus dans la conversion nombre vers chaîne. * from (from_), to : définissent les limites de l'échelle. from est relatif à la gauche ou au haut de l'échelle et to à la droite ou au bas de l'échelle. * label : étiquette du widget, placé en haut (à haut à gauche si horizontal, en haut à droite si vertical). * orient : l'orientation peut être HORIZONTAL="horizontal" ou VERTICAL="vertical". * repeatdelay, repeatinterval : délai avant que la répétition ne démarre si on presse la souris dans la gouttière et intervalle de la répétition. L'unité est la milliseconde. * resolution : à -1, il n'y a pas de résolution bien définie. Sinon, l'échelle peut être «graduée» avec resolution et le slider se déplace par sauts de la valeur donnée. * showvalue : booléen qui règle l'affichage des repères chiffrés le long de la gouttière. * sliderlength : longueur du slider en pixels. * sliderrelief : relief du slider (par défaut, RAISED). * state : Les valeurs possible sont NORMAL="normal", ACTIVE="acrive" et DISABLED="disabled". L'état DISABLED «gèle» le widget. * tickinterval : définit les repères numérotés le long de la gouttière. La valeur se fait en fonction de l'échelle retenue et de la densité des repères souhaitée. * variable : variable est un StringVar, un IntVar ou un DoubleVar. Le fonctionnement est semblable à celui déjà rencontré pour le widget Entry. * width : largeur de la gouttière du widget en pixels. * length : longueur de la gouttière du widget en pixels. 'activebackground': ('activebackground', 'activeBackground', 'Foreground', , '#ececec'), 'background': ('background', 'background', 'Background', , '#d9d9d9'), 'bd': ('bd', '-borderwidth'), 'bg': ('bg', '-background'), 'bigincrement': ('bigincrement', 'bigIncrement', 'BigIncrement', 0, 0.0), 'borderwidth': ('borderwidth', 'borderWidth', 'BorderWidth', , 1), 'command': ('command', 'command', 'Command', '', ''), 'cursor': ('cursor', 'cursor', 'Cursor', '', ''), 'digits': ('digits', 'digits', 'Digits', 0, 0), 'fg': ('fg', '-foreground'), 'font': ('font', 'font', 'Font', , 'Courier -25 bold'), 'foreground': ('foreground', 'foreground', 'Foreground', , '#000000'), 'from': ('from', 'from', 'From', 0, 0.0), 'highlightbackground': ('highlightbackground', 'highlightBackground', 'HighlightBackground', , '#d9d9d9'), 'highlightcolor': ('highlightcolor', 'highlightColor', 'HighlightColor', , '#000000'), 'highlightthickness': ('highlightthickness', 'highlightThickness', 'HighlightThickness', , 1), 'label': ('label', 'label', 'Label', '', ''), 'length': ('length', 'length', 'Length', , 400), 'orient': ('orient', 'orient', 'Orient', , 'horizontal'), 'relief': ('relief', 'relief', 'Relief', , 'flat'), 'repeatdelay': ('repeatdelay', 'repeatDelay', 'RepeatDelay', 300, 300), 'repeatinterval': ('repeatinterval', 'repeatInterval', 'RepeatInterval', 100, 100), 'resolution': ('resolution', 'resolution', 'Resolution', 1, 1.0), 'showvalue': ('showvalue', 'showValue', 'ShowValue', 1, 1), 30), 'sliderrelief': ('sliderrelief', 'sliderRelief', 'SliderRelief', , 'raised'), 'state': ('state', 'state', 'State', , 'normal'), 'takefocus': ('takefocus', 'takeFocus', 'TakeFocus', '', ''), 'tickinterval': ('tickinterval', 'tickInterval', 'TickInterval', 0, 0.0), 'to': ('to', 'to', 'To', 100, 100.0), 'troughcolor': ('troughcolor', 'troughColor', 'Background', , '#b3b3b3') 'variable': ('variable', 'variable', 'Variable', '', ''), 'width': ('width', 'width', 'Width', , 25), 3. les méthodes du widget Scale* get () : retourne la valeur actuelle de l'échelle. * set (valeur) ; fixe la valeur actuelle de l'échelle. Ces deux méthodes peuvent être court-circuitées par l'usage de l'attribut variable. * identify (x, y) : (x, y) étant les coordonnées du pointeur de souris sur le widget, retourne une référene sur la partie survolée : ce peut être "slider", "though1", "though2", "none". * coords (valeur=None) : retourne un tuple (x, y) du point de la ligne centrale de la gouttière qui correspond à valeur ; retourne la valeur courante correspondant au centre du slider si aucun paramètre n'est donné. les coordonnées sont relatives au widget. tk23 : SpinboxUn widget Spinbox est un composant fenêtré qui présente deux parties : une zone d'affichage où on peut afficher un nombre ou une chaîne de caractères et une zone latérale avec deux boutons. Ces boutons permettent d'incrémenter/décrémenter les valeurs numériques affichées, ou d'évoluer sur une liste fixe de chaînes. Le widget Spinbox peut être en lecture seulement (affichage, copie), en lecture/écriture (on peut saisir au clavier la valeur dans le widget), ou simplement inactivé. 1. le constructeursyntaxe widget = Spinbox (conteneur, options) exemples :
readonlybackground="#e0e0e0") (side="left", padx=20, pady=10) # Spinbox chaîne lecture liste = [" blanc "," rouge "," vert "," bleu "," jaune ", " magenta "," cyan "," noir "] spinChaine =Spinbox(racine, font=maFonte, values=liste, width=9, readonlybackground="#e0e0e0", justify="center", state="readonly") (side="right", padx=20, pady=10) racine.mainloop() # fichier : tk23ex00 2. les options2.1. la liste des options option communes : activebackground, background, bd, bg, borderwidth, cursor, disabledbackground, disabledforeground, font, foreground, highlightbackground, highlightcolor, highlightthickness, relief, selectbackground, selectborderwidth, selectforeground 2.2. les options spécifiquesoptions semblables à celles du widget Entry : exportselection, insertbackground,insertborderwidth, insertofftime, insertontime, insertwidth, invalidcommand, justify, takefocus, textvariable, validate, validatecommand, width, xscrollcommand options spécifiques au widget : option sur les boutons fléchés : * buttonbackground : couleur de fond sur la partie où il y a les boutons fléchés. * buttoncursor : curseur lorsque la souris est sur les boutons flèches. * buttondownrelief, buttonuprelief : relief des boutons fléchés (enfoncé, relâché). * repeatdelay : fixe le temps où on peut laisser le bouton fléché enfoncé avant que l'action se répète ; la durée en deux répétions est fixée par repeatinterval. * repeatinterval : en liaison avec repeatdelay. * command : gestionnaire correspondant à l'événement clic sur un des boutons fléchés. Attention, une entré clavier n'appelle rien. * wrap : permet de faire défiler l'affichage en boucle à m'aide des boutons fléchés. options numériques : * format : affiche les valeurs numériques avec un format python classique. Par exemple, "% 12.7f" implique un affichage sur 12 caractères, dont 7 décimales. L'option justify s'applique. * from (écrire from_), to : dans le cas d'un affichage numérique, fixe les deux bornes, inférieure et supérieure de l'échelle des nombres impliquée. * increment : fixe l'incrément de parcours de l'échelle . options chaînes : * values : cette option est incompatible avec les options numériques. La valeur de values est un liste (ou tuple) de chaînes de caractères qui peut être balayée par action sur les touches fléchées. option sur les états : * state : il y a trois états possibles : NORMAL="normal", DISABLED="disabled", et "readonly". En état NORMAL, on peut lire, écrire (clavier), sélectionner ; on ne peut pas écrire dans l'état "readonly". * readonlybackground : les options d'arrière plan en état NORMAL et DISABLED sont partagées. L'option présente est spécifique et s'applique à la troisième. 'activebackground': ('activebackground', 'activeBackground', 'Background', , '#ececec'), '#ffffff'), 'bd': ('bd', '-borderwidth'), 'bg': ('bg', '-background'), 'borderwidth': ('borderwidth', 'borderWidth', 'BorderWidth', , 1), 'buttonbackground': ('buttonbackground', 'Button.background', 'Background', , '#d9d9d9'), 'buttoncursor': ('buttoncursor', 'Button.cursor', 'Cursor', '', ''), 'buttondownrelief': ('buttondownrelief', 'Button.relief', 'Relief', , 'raised'), 'buttonuprelief': ('buttonuprelief', 'Button.relief', 'Relief', , 'raised'), 'command': ('command', 'command', 'Command', '', ''), 'cursor': ('cursor', 'cursor', 'Cursor', , 'xterm'), 'disabledbackground': ('disabledbackground', 'disabledBackground', 'DisabledBackground', , '#d9d9d9'), 'disabledforeground': ('disabledforeground', 'disabledForeground', 'DisabledForeground', , '#a3a3a3'), 'exportselection': ('exportselection', 'exportSelection', 'ExportSelection', 1, 1), 'fg': ('fg', '-foreground'), 'font': ('font', 'font', 'Font', , 'Helvetica -30'), 'foreground': ('foreground', 'foreground', 'Foreground', , '#000000'), 'format': ('format', 'format', 'Format', '', ''), 'from': ('from', 'from', 'From', 0, 0.0), 'highlightbackground': ('highlightbackground', 'highlightBackground', 'HighlightBackground', , '#d9d9d9'), 'highlightcolor': ('highlightcolor', 'highlightColor', 'HighlightColor', , '#000000'), 'highlightthickness': ('highlightthickness', 'highlightThickness', 'HighlightThickness', , 1), 'increment': ('increment', 'increment', 'Increment', 1, 1.0), 'insertbackground': ('insertbackground', 'insertBackground', 'Foreground', , '#000000'), , 0),
|