Tcl / Tk
Le widget texte de Tk
Auteur :
Arnaud LAPREVOTE
Linbox Free&ALter Soft
152, rue de Grigy
57070 METZ
tel: 03 87 50 87 90 - 06 11 36 15 30
fax : 03 87 75 19 26
Email : arnaud.laprevote@linbox.com
1. Le widget text
Les widgets que nous avons vu jusqu'ici sont simples (bouton, label, entrée de texte, frame, ...). Nous allons examiner maintenant des widgets complexes, des supports quasi idéals pour des applications complexes.Le widget texte est un widget d'entrée et d'affichage de texte avec de nombreuses possibilités d'enluminure. Vous pourrez choisir la fonte de chaque portion de texte, la couleur, la taille, la justification, créer des hyperliens, ajouter des images, ou n'importe quel autre widget à l'intérieur. Bref, vous avez un nombre de possibilités énorme. Ce n'est malheureusement pas aussi complet qu'un widget d'affichage html, mais cela n'est vraiment pas loin.
En raison de la richesse du widget, il est difficile de faire un traitement exhaustif. Nous nous contenterons donc dans la suite de présenter les possibilités essentielles. Si vous souhaitez tout savoir dans le détail, merci de vous reporter à l'aide sur le widget texte (taper la commande "man text" sous unix).
En route, tout d'abord un exemple de résultat :

Et le code associé (fichier test/wid_text.tcl) :
#!/home/arnaud/source/tcltk83/bin/wish8.3 text .text -height 30 -width 80 -yscrollcommand ".scroll set" scrollbar .scroll -command ".text yview" pack .scroll -side right -fill y pack .text -expand yes -fill both set text .text set title_font [font create title_font -family times -size 20 \ -weight bold] set title {Le widget text} $text tag configure BODY -foreground black -background white $text tag configure TITLE -foreground "#808000" \ -font title_font -justify center $text tag configure H1 -foreground blue -font helvetica $text tag configure H2 -foreground green -font courrier $text tag configure LISTE0 -foreground black -lmargin1 20 $text tag configure P -foreground black $text tag configure PRE -foreground black -background grey $text insert end {Le widget text } TITLE $text mark set "1." insert $text insert end {1. Changement de fontes et ancre pour les déplacements } H1 $text mark set "1.1." insert $text insert end {1.1. Encore d'autres fontes } H2 $text insert end {Evidemment, on peut faire du texte tout simple, } TEXT $text insert end {ou alors le décalé (ici à gauche mais aussi à droite) } LISTE0 $text insert end { Ou des choses plus sophistiquées : } TEXT $text insert end {#!/usr/bin/tclsh puts "Hello world" } PRE # open_IMG image create photo im0 -file img/exemple.gif $text image create end -image im0 -align center -pady 10 -padx 100 $text insert end "\n" button $text.button0 -text button -command exit $text window create end -window $text.button0 -align center -padx 100 $text insert end { That's all folks ! } TEXT
2. Création du widget
Le code suivant permet la création du widget et d'une barre de déroulement verticale associée :
text .text -height 30 -width 80 -yscrollcommand ".scroll set" scrollbar .scroll -command ".text yview" pack .scroll -side right -fill y pack .text -expand yes -fill both
Ici on crée le widget texte avec une hauteur de 30 lignes et une largeur de 80 caractères et l'on indique que le déroulement de la fenêtre dépend de la valeur du widget .scroll.
On crée ensuite ce widget .scroll et l'on indique que lors des mouvements de la barre, il faut réafficher le widget text.
Enfin, on place le widget text et la barre défilement verticale l'un à côté de l'autre et l'on demande que lors des chagement de dimension le widget text voit sa taille augmentée.
Les raccourcis claviers classiques d'emacs sont disponibles dans un widget text pour aller en début (Ctrl-a) ou en fin de ligne (Ctrl-e).
Les commandes génériques disponibles sont maintenant :
| .widget_text insert | insertion de texte dans le widget, |
| .widget_text tag | manipulation de tags permettant de changer les formats de portions de texte, |
| .widget_text mark | marquage d'une position dans le texte, |
| .widget_text image | manipulation d'images dans le widget texte, |
| .widget_text window | manipulation de fenêtres pouvant contenir des widgets dans le widget text, |
| .widget_text search | recherche dans le widget d'une chaine de caractères, |
| .widget_text cget | permet de consulter la valeur d'une option du widget, |
| .widget_text configure | permet de configurer les options du widget, |
| .widget_text delete | permet de supprimer des portions du contenu du widget, |
| .widget_text dump | récupération d'une portion ou de la totalité du contenu du widget sous forme de liste, |
| .widget_text get | récupération d'une portion ou de la totalité du texte du widget, |
| .widget_text see | ajuste l'affichage pour montrer un endroit précis du texte, |
| .widget_text xview | ajustement de l'affichage à l'horizontal, |
| .widget_text yview | ajustement de l'affichage en vertical |
La plupart des commandes utilise des indices pour spécifier des portions du widgt. Un indice peut avoir la forme suivante :
| line.char | Le caractère n° char (commençant à 0) de la ligne n° line (commençant à 1) |
| 1.10 | le 11ème caractère de la 1ère ligne |
| @x,y | Le caractère sous le pixel de la ligne x colonne y |
| @0,0 | Le caractère en haut à gauche de l'écran |
| end | Le caractère juste après le dernier saut de ligne |
| marque | Le caractère juste après la marque marque |
| nomdetag.first | Le premier caractère de la zone nomdetag |
| nomdetag.last | Le caractère juste après le dernier caractère de la zone nomdetag |
| nomdefenetre | La position de la fenêtre ayant ce nom |
Il est possible de rafiner encore ces positions en y associant des modificateurs tels que
| + valeur chars | valeur caractères après la position précédemment définie |
| - valeur chars | valeur caractères avant la position précédemment définie |
| + valeur lines | valeur lignes après la position précédemment définie |
| - valeur lines | valeur lignes avant la position précédemment définie |
| linestart | Début de la ligne |
| lineend | Fin de la ligne |
| wordstart | Début du mot |
| wordend | Fin du mot |
On pourra donc lire :
set 4linetext [.text get {end - 4 lines } end]
3. Insertion, récupération et recherche de texte
Pour insérer un texte, rien de plus simple :.text insert 1.0 "Insertion de texte"
On peut aussi associer le texte insérer à un tag (en fait un style):
.text insert end "Un titre" titre1Ou même à plusieurs :
.text insert 1.0 "Un titre en gras" [list titre1 gras]
Pour récupérer un texte on utilise get :
set titre [.text get 1.0 {1.0 lineend}]
Il est aussi possible d'avoir le contenu complet du widget (texte, tag, mark, image, fenêtre embarquée) grâce au dump.
set full_content [.text dump 1.0 end]Il est simple à partir de ce résultat de faire une moulinettre qui recrée le widget texte à partir de ce contenu. Le résultat est une liste dont les éléments sont :
type_d_entree valeur indexD'où par exemple :
tagon TITLE 1.0 \
tagon gras 1.0 \
tagon titre1 1.0 \
text {Un titre en gras} 1.0 \
tagoff gras 1.16 \
text {Un titre} 1.16 \
tagoff titre1 1.24 \
text {Insertion de texte} 1.24 \
tagoff TITLE 1.42 \
window .text.b1 1.42 \
mark current 1.43 \
mark insert 1.43 \
text {
} 1.43
Une commande search permet de faire toutes les recherches que l'on veut dans le texte.
.text search -regexp {[Tt]it} 1.0 end
Les options de la recherche sont :
| Option | Signification |
| -forward | Recherche à partir du début |
| -backward | Recherche à partir de la fin |
| -exact | Recherche exacte |
| -regexp | Recherche sur expression régulière |
| -nocase | Sans tenir compte des majuscules/minuscules |
| -count nom_de_variable | Si l'on trouve, stocke le nombre de caractères de correspondance dans la variable nom_de_variable |
| -- | Arrêt des options |
4. Mais quels sont donc ces tags, qui tapent sur vos têtes ?
Les tags permettent de choisir les caractéristiques visuelles de la ou des portions de texte marquées. L'utilisation des tags se fait en 2 temps. Il faut d'abord créer le tag et les caractéristiques associées, puis l'utiliser sur le texte.La syntaxe de la création est la suivante :
.text tag configure TITLE -font nom_d_une_fonte -justify center
On peut préciser un tag à l'insertion :
.text insert end "Le titre du document" TITLEOu bien demander à appliquer un tag à une portion de texte :
.text tag add TITLE 1.0 {1.0 lineend}
Les caractéristiques modifiables sont :
| Option | Effet |
| -background couleur | Couleur de fond pour le tag |
| -bgstipple bitmap | Un bitmap utilisé en motif de fond |
| -borderwidth nombre_de_pixels | Largeur du bord en pixels |
| -elide booléen | Affiché ou non |
| -fgstipple bitmap | Un bitmap utilisé en motif pour l'avant plan (le texte) |
| -font nom_d_une_fonte | Fonte utilisée |
| -foreground couleur | Couleur du texte |
| -justify left/right/center | Justification (gauche, droite ou centrée) du texte |
| -lmargin1 nombre_de_pixels | Marge à droite pour la première ligne |
| -lmargin2 nombre_de_pixels | Marge à gauche pour les lignes autres que la première |
| -offset nombre_de_pixels | Décalage vers le haut par rapport à la ligne de base du texte |
| -overstrike booléen | Texte barré |
| -relief raised/sunken/flat/ridge/solid/groove | Aspect "3d"des bords du texte |
| -rmargin nombre_de_pixels | Marge à droite |
| -spacing1 nombre_de_pixels | Espace additionnel laissé au-dessus des lignes de texte. Si le texte se replie, ne s'applique qu'à la première ligne |
| -spacing2 nombre_de_pixels | Pour les lignes se repliant, spécifie l'espace à laisser au-dessus des lignes replièes |
| -spacing3 nombre_de_pixels | Espace laissé sous les lignes. Si les lignes se replient, ne s'applique qu'à la dernière ligne |
| -tabs liste_de_tabulation | Liste de tabulation pour la portion de texte (détails dans le manuel) |
| -underline booléen | Texte souligné |
| -wrap none/char/word | Type de repliement appliqué au texte |
Il est possible d'associer des actions à des tags. Cela se fait avec la syntaxe :
nom_du_widget tag bind evénement scriptPar exemple :
.text tag bind TITLE <Button-1> { puts "Yahoo" }
On peut supprimer un tag avec la commande :
.text tag delete TITLE
Ou empécher son application sur une portion de texte par :
.text tag remove TITLE 1.0
Et connaître la liste des tags disponibles par :
.text tag namesOu pour une section par
.text tag names 1.0
5. Et avec des images en plus
Si vous avez une image vous pouvez l'afficher dans le texte.
image photo create im1 -file img/exemple.gif .text image create end -image im1Et voila. Vous trouverez le détail des options associées à la commande image du widget texte dans le manuel de texte.
6. Et même d'autres widgets
John ne s'est pas arrêté sur sa lancée et il est donc possible d'inclure n'importe quel tag dans un widget text. On utilise pour cela des "fenêtres embarquées" (embedded windows).Donc il vous suffit d'avoir un widget quelconque et hop là !
button .text.b1 -text "Bye Bye" -command exit .text window create end -window .b1
Là encore de nombreuses options sont possibles.
7. Les Marques jaunes ?
Il est possible de placer des balises dans le texte qui sont appelées des marques (comme des marque-pages)..text mark set "title0" 1.0
Les autres commandes associées aux marques sont :
| Commande | Action |
| widget mark gravity | Montre ou initialise l'attachement d'une marque vers les caractères de gauche ou de droite |
| widget mark names | Liste des marques disponibles |
| widget mark next indice | Prochaine marque disponible à la positionindice |
| widget mark previous indice | Précédente marque disponible à la positionindice |
| widget mark set nom_de_marque indice | Insertion de la marque nom_de_marque à la position indice |
| widget mark unset nom_de_marque | Suppression de la marque nom_de_marque |
Les marques suivantes sont constamment et automatiquement créées et indestructibles :
- insert : marque du curseur courant d'insertion,
- current : est associé au caractère le plus proche de la souris.
8. Couper, copier, coller, dodo
Les commandes selection et clipboard permettent de faire l'essentiel du boulot.set sel [ selection get ]selection get renvoie le contenu de la sélection courrante.
clipboard clear clipboard append [selection get]Insertion dans le presse-papier de la zone sélectionnée après nettoyage du clipboard.
Le tag sel contient la zone de texte sélectionnée. Donc on peut aussi supprimer le contenu de cette zone :
.text delete sel.first sel.last
Enfin, pour récupérer le contenu du presse-papier on utilise la commande.
set clip [selection get -selection CLIPBOARD]



