IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)

Apprendre à utiliser le module Python PyGTK 2.0


précédentsommairesuivant

13. Chapitre 13. Le widget TextView

13-1. Présentation des widgets de texte

Le widget TextViewTextView : la zone de texte (zone de texte) ainsi que les objets qui lui sont associés (TextBufferTextBuffer : le buffer de texte, TextMarkTextMark : les marques de texte, TextIterTextIter : les itérateurs de texte, TextTagLes TextTag et TextTagTableLa TextTagTable) offrent une structure puissante d'édition de texte multiligne.

Un TextBufferTextBuffer : le buffer de texte (buffer de texte) contient le texte qui est affiché par un ou plusieurs widgets TextViewTextView : la zone de texte. Avec GTK+ 2.0 le texte est encodé en UTF-8, ce qui signifie qu'un caractère peut être encodé avec plusieurs octets. Dans un TextBufferTextBuffer : le buffer de texte on doit bien faire la distinction entre le décompte des caractères (appelé offset) et le décompte des octets (appelé index).

Les TextIterTextIter : les itérateurs de texte (itérateurs de texte) permettent une représentation volatile d'une position dans un TextBufferTextBuffer : le buffer de texte, située entre deux caractères. Les TextIterTextIter : les itérateurs de texte ne sont valables que tant que le nombre de caractères dans le TextBufferTextBufferTextBuffer : le buffer de texte est inchangé. Chaque fois que l'on insère ou efface des caractères dans un TextBufferTextBuffer : le buffer de texte tous les TextIterTextIterTextIter : les itérateurs de texte sont invalidés. Les TextIterTextIter : les itérateurs de texte sont le moyen le plus utilisé de spécifier des positions dans un TextBufferTextBuffer : le buffer de texte afin d'y manipuler du texte.

Les TextMarkTextMark : les marques de texte (marques de texte) permettent de marquer des positions qui ne seront pas affectées par les modifications du TextBufferTextBuffer : le buffer de texte. Une marque est comme un TextIterTextIter : les itérateurs de texte (elle représente une position entre deux caractères d'un TextBufferTextBuffer : le buffer de texte) à la différence que si l'on efface le texte qui l'entoure elle reste à l'endroit où était le texte effacé. Si l'on insère du texte à la position indiquée par cette marque, celle-ci se retrouvera soit à gauche, soit à droite du texte inséré, en fonction de la gravité de la marque — la marque restera à droite du texte inséré dans le cas d'une gravité à droite, et à gauche dans le cas d'une gravité à gauche. On peut choisir de donner un nom à une TextMarkTextMark : les marques de texte, ou bien la laisser anonyme. Chaque TextBufferTextBuffer : le buffer de texte comporte deux TextMarkTextMark : les marques de texte prédéfinies, nommées insert et selection_bound, faisant référence aux positions respectives du point d'insertion et de la fin de la sélection (la sélection est comprise entre les marques insert et selection_bound).

Les objets TextTagLes TextTag (balises de texte) spécifient un ensemble d'attributs pouvant être appliqués à une portion de texte d'un TextBufferTextBufferTextBuffer : le buffer de texte. Chaque TextBufferTextBuffer : le buffer de texte a une TextTagTableLa TextTagTable (table des balises de texte) qui recense les balises disponibles dans ce buffer. Plusieurs TextBufferTextBuffer : le buffer de texte peuvent se partager la même TextTagTableLa TextTagTable pour offrir une meilleure cohérence. On utilise souvent les TextTagLes TextTag pour modifier l'apparence d'une portion de texte mais elles peuvent tout aussi bien servir à empêcher l'édition de cette même portion de texte.

13-2. TextView : la zone de texte

Il n'y a qu'une fonction pour créer un nouveau widget TextView.

 
Sélectionnez
  textview = gtk.TextView(buffer=None)

Le fait de créer une TextView entraîne aussi la création d'un TextBufferTextBuffer : le buffer de texte et d'une TextTagTableLa TextTagTable par défaut qui lui seront associés. Si vous souhaitez utiliser un TextBufferTextBufferTextBuffer : le buffer de texte existant pour votre TextView, spécifiez-le dans la méthode ci-dessus. Pour changer le TextBufferTextBuffer : le buffer de texte utilisé par une TextView, utilisez la méthode suivante :

 
Sélectionnez
  textview.set_buffer(buffer)

Utilisez la méthode suivante pour obtenir une référence au TextBufferTextBuffer : le buffer de texte d'une TextView :

 
Sélectionnez
  buffer = textview.get_buffer()

Le widget TextView n'a pas de barres de défilement pour ajuster la vue quand le texte dépasse de la fenêtre. Pour lui en donner, vous devez placer votre TextView dans une ScrolledWindow (pas encore traduit).

Vous pouvez utiliser une TextView pour permettre à l'utilisateur d'éditer un texte ou bien pour afficher plusieurs lignes d'un texte en lecture seule. Pour passer d'un mode à l'autre, faites appel à la méthode suivante :

 
Sélectionnez
  textview.set_editable(choix)

L'argument choix prend la valeur TRUE ou FALSE pour préciser si l'utilisateur est autorisé à éditer le contenu du widget TextView ou non. Le mode d'édition de la TextView peut être modifié pour des portions de texte du TextBufferTextBuffer : le buffer de texte par l'intermédiaire des TextTagLes TextTag.

On retrouve le mode d'édition courant avec la méthode suivante :

 
Sélectionnez
  edition = textview.get_editable()

Lorsque la TextView n'est pas éditable, vous devriez probablement masquer le curseur en utilisant cette méthode :

 
Sélectionnez
  textview.set_cursor_visible(choix)

L'argument choix prend la valeur TRUE ou FALSE pour préciser si le curseur doit être visible.

Le widget TextView peut ajuster la largeur du texte à la fenêtre d'affichage grâce au retour à la ligne automatique. Cette option n'est pas activée par défaut mais peut l'être à tout moment grâce à la méthode qui suit :

 
Sélectionnez
  textview.set_wrap_mode(choix)

Cette méthode vous permet d'indiquer si la coupure du retour à la ligne automatique doit s'effectuer après le dernier caractère de la ligne, ou bien si ce dernier doit préserver l'intégrité des mots. L'argument choix est à choisir parmi :

 
Sélectionnez
1.
2.
3.
  gtk.WRAP_NONE    # pas de retour à la ligne automatique
  gtk.WRAP_CHAR    # couper après le dernier caractère de la ligne
  gtk.WRAP_WORD    # couper après le dernier mot de la ligne

L'alignement par défaut du texte peut être défini et récupéré avec les méthodes :

 
Sélectionnez
  textview.set_justification(alignement)
  alignement = textview.get_justification()

alignement peut être :

 
Sélectionnez
1.
2.
3.
  gtk.JUSTIFY_LEFT      # aligné à gauche
  gtk.JUSTIFY_RIGHT     # aligné à droite
  gtk.JUSTIFY_CENTER    # centré

Le texte sera aligné à gauche (JUSTIFY_LEFT) si le retour à la ligne automatique est désactivé (WRAP_NONE). L'alignement par défaut peut toutefois être modifié avec des TextTagLes TextTag dans le TextBufferTextBuffer : le buffer de texte correspondant.

Parmi les autres attributs de texte, la marge gauche, la marge droite, les tabulations et l'indentation des paragraphes peuvent être définis et récupérés avec les méthodes suivantes :

 
Sélectionnez
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
  textview.set_left_margin(marge_gauche)
  marge_gauche = textview.get_left_margin()
  
  textview.set_right_margin(marge_droite)
  marge_droite = textview.get_right_margin()
  
  textview.set_indent(indentation)
  indentation = textview.get_indent()
  
  textview.set_pixels_above_lines(pixels_au_dessus_de_la_ligne)
  pixels_au_dessus_de_la_ligne = textview.get_pixels_above_lines()
  
  textview.set_pixels_below_lines(pixels_au_dessous_de_la_ligne)
  pixels_au_dessous_de_la_ligne = textview.get_pixels_below_lines()
  
  textview.set_pixels_inside_wrap(pixels_retour_a_la_ligne)
  pixels_retour_a_la_ligne = textview.get_pixels_inside_wrap()
  
  textview.set_tabs(tabulations)
  tabulations = textview.get_tabs()

marge_gauche, marge_droite, indentation, pixels_au_dessus_de_la_ligne, pixels_au_dessous_de_la_ligne et pixels_retour_a_la_ligne doivent être indiqués en pixels. Ces valeurs par défaut peuvent être modifiées en employant des TextTagLes TextTag dans le TextBufferTextBuffer : le buffer de texte correspondant. tabs doit être un pango.TabArray.

Le programme d'exemple textview-basic.py illustre l'utilisation basique du widget TextView :

Image non disponible
Figure 13.1. Exemple basique de TextView

Le code source du programme est le suivant :

 
Sélectionnez
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
105.
106.
107.
108.
109.
110.
111.
112.
113.
114.
115.
116.
117.
118.
119.
120.
121.
122.
123.
124.
125.
126.
127.
128.
129.
130.
131.
132.
133.
134.
135.
136.
137.
138.
139.
140.
141.
142.
143.
144.
145.
146.
147.
148.
149.
150.
151.
152.
153.
154.
155.
156.
157.
158.
159.
160.
161.
162.
163.
164.
165.
#!/usr/bin/env python

# exemple textview-basic.py
  
import pygtk
pygtk.require('2.0')
import gtk

class ExempleTextView:
    def change_editable(self, case, textview):
        textview.set_editable(case.get_active())

    def change_curseur_visible(self, case, textview):
        textview.set_cursor_visible(case.get_active())

    def change_marge_gauche(self, case, textview):
        if case.get_active():
            textview.set_left_margin(50)
        else:
            textview.set_left_margin(0)

    def change_marge_droite(self, case, textview):
        if case.get_active():
            textview.set_right_margin(50)
        else:
             textview.set_right_margin(0)

    def change_retour_ligne(self, boutonradio, textview, val):
        if boutonradio.get_active():
            textview.set_wrap_mode(val)

    def change_alignement(self, boutonradio, textview, val):
        if boutonradio.get_active():
            textview.set_justification(val)

    def fermer_application(self, widget):
        gtk.main_quit()

    def __init__(self):
        fenetre = gtk.Window(gtk.WINDOW_TOPLEVEL)
        fenetre.set_resizable(True)
        fenetre.connect("destroy", self.fermer_application)
        fenetre.set_title("Exemple de widget TextView simple")
        fenetre.set_border_width(0)

        boite1 = gtk.VBox(False, 0)
        fenetre.add(boite1)
        boite1.show()

        boite2 = gtk.VBox(False, 10)
        boite2.set_border_width(10)
        boite1.pack_start(boite2, True, True, 0)
        boite2.show()

        fd = gtk.ScrolledWindow()
        fd.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
        textview = gtk.TextView()
        buffertexte = textview.get_buffer()
        fd.add(textview)
        fd.show()
        textview.show()

        boite2.pack_start(fd)
        # Chargement du fichier textview-basic.py dans la fenêtre
        fichier = open("textview-basic.py", "r")

        if fichier:
            chaine = fichier.read()
            fichier.close()
            buffertexte.set_text(chaine)

        boiteH = gtk.HButtonBox()
        boite2.pack_start(boiteH, False, False, 0)
        boiteH.show()

        boiteV = gtk.VBox()
        boiteV.show()
        boiteH.pack_start(boiteV, False, False, 0)
        # case à cocher pour autoriser l'édition du texte
        case = gtk.CheckButton("Editable")
        boiteV.pack_start(case, False, False, 0)
        case.connect("toggled", self.change_editable, textview)
        case.set_active(True)
        case.show()
        # case à cocher pour afficher le curseur
        case = gtk.CheckButton("Curseur visible")
        boiteV.pack_start(case, False, False, 0)
        case.connect("toggled", self.change_curseur_visible, textview)
        case.set_active(True)
        case.show()
        # case à cocher pour afficher une marge gauche
        case = gtk.CheckButton("Marge gauche")
        boiteV.pack_start(case, False, False, 0)
        case.connect("toggled", self.change_marge_gauche, textview)
        case.set_active(False)
        case.show()
        # case à cocher pour afficher une marge droite
        case = gtk.CheckButton("Marge droite")
        boiteV.pack_start(case, False, False, 0)
        case.connect("toggled", self.change_marge_droite, textview)
        case.set_active(False)
        case.show()
        # boutons radio pour définir le type de retour à la ligne automatique
        boiteV = gtk.VBox()
        boiteV.show()
        boiteH.pack_start(boiteV, False, False, 0)
        radio = gtk.RadioButton(None, "WRAP__NONE")
        boiteV.pack_start(radio, False, True, 0)
        radio.connect("toggled", self.change_retour_ligne, textview, gtk.WRAP_NONE)
        radio.set_active(True)
        radio.show()
        radio = gtk.RadioButton(radio, "WRAP__CHAR")
        boiteV.pack_start(radio, False, True, 0)
        radio.connect("toggled", self.change_retour_ligne, textview, gtk.WRAP_CHAR)
        radio.show()
        radio = gtk.RadioButton(radio, "WRAP__WORD")
        boiteV.pack_start(radio, False, True, 0)
        radio.connect("toggled", self.change_retour_ligne, textview, gtk.WRAP_WORD)
        radio.show()

        # boutons radio pour définir l'alignement
        boiteV = gtk.VBox()
        boiteV.show()
        boiteH.pack_start(boiteV, False, False, 0)
        radio = gtk.RadioButton(None, "JUSTIFY__LEFT")
        boiteV.pack_start(radio, False, True, 0)
        radio.connect("toggled", self.change_alignement, textview,
                      gtk.JUSTIFY_LEFT)
        radio.set_active(True)
        radio.show()
        radio = gtk.RadioButton(radio, "JUSTIFY__RIGHT")
        boiteV.pack_start(radio, False, True, 0)
        radio.connect("toggled", self.change_alignement, textview,
                      gtk.JUSTIFY_RIGHT)
        radio.show()
        radio = gtk.RadioButton(radio, "JUSTIFY__CENTER")
        boiteV.pack_start(radio, False, True, 0)
        radio.connect("toggled", self.change_alignement, textview,
                      gtk.JUSTIFY_CENTER)
        radio.show()

        separateur = gtk.HSeparator()
        boite1.pack_start(separateur, False, True, 0)
        separateur.show()

        boite2 = gtk.VBox(False, 10)
        boite2.set_border_width(10)
        boite1.pack_start(boite2, False, True, 0)
        boite2.show()

        bouton = gtk.Button("Fermer")
        bouton.connect("clicked", self.fermer_application)
        boite2.pack_start(bouton, True, True, 0)
        bouton.set_flags(gtk.CAN_DEFAULT)
        bouton.grab_default()
        bouton.show()
        fenetre.show()

def main():
    gtk.main()
    return 0

if __name__ == "__main__":
    ExempleTextView()
    main()

Aux lignes 10 à 34, on définit les fonctions de rappel des cases à cocher et des boutons radio, que l'on utilisera pour changer les attributs par défaut de la TextView. Aux lignes 55 à 63, on crée une ScrolledWindow pour contenir la TextView. La ScrolledWindow est placée dans une VBox avec les cases à cocher et les boutons radio créés aux lignes 72 à 140. Le TextBufferTextBuffer : le buffer de texte associé à la TextView est chargé avec le contenu du fichier source aux lignes 64 à 70.

13-3. TextBuffer : le buffer de texte

Le TextBuffer est le composant principal du système d'édition de texte de PyGTK. Il contient le texte, les TextTagLes TextTag (dans une TextTagTableLa TextTagTable), et les TextMarkTextMark : les marques de texte, qui, ensemble, décrivent comment le texte doit être affiché et permettent à l'utilisateur de modifier interactivement le texte ou la manière dont il s'affiche. Comme nous l'avons fait remarquer dans la section précédente, un TextBuffer est associé à un ou plusieurs TextViewTextView : la zone de texte, qui se chargent d'afficher son contenu.

La création d'un TextBuffer se fait soit automatiquement lorsque l'on crée un TextViewTextView : la zone de texte, soit avec la fonction :

 
Sélectionnez
  bufferdetexte = TextBuffer(table=None)

table est une TextTagTableLa TextTagTable. Si table n'est pas spécifié (ou s'il vaut None), une nouvelle TextTagTableLa TextTagTable sera créée pour le TextBuffer.

Un grand nombre de méthodes est disponible pour :

  • insérer et supprimer du texte dans un buffer ;
  • créer, supprimer et manipuler des marques ;
  • manipuler le curseur et la sélection ;
  • créer, appliquer et supprimer des balises ;
  • spécifier et manipuler des TextIterTextIter : les itérateurs de texte ;
  • récupérer des informations sur l'état du buffer.

13-3-1. Récupérer des informations sur le buffer

Vous pouvez récupérer le nombre de lignes d'un TextBuffer avec la méthode :

 
Sélectionnez
  nombre_lignes = bufferdetexte.get_line_count()

De la même manière, vous pouvez obtenir le nombre de caractères présents dans le TextBuffer :

 
Sélectionnez
  nombre_caract = bufferdetexte.get_char_count()

Lorsque le contenu du TextBuffer est modifié, le drapeau de modification est levé. L'état de ce drapeau peut être obtenu à l'aide de la méthode :

 
Sélectionnez
  modif = bufferdetexte.get_modified()

Si le programme sauvegarde le contenu du buffer, la méthode suivante peut réinitialiser le drapeau de modification :

 
Sélectionnez
  bufferdetexte.set_modified(choix)

13-3-2. Créer des TextIter

On utilise les TextIterTextIterTextIterTextIter : les itérateurs de texte pour spécifier une position entre deux caractères d'un TextBuffer. Les méthodes du TextBuffer qui manipulent du texte s'en servent pour indiquer à quelle position elles doivent s'appliquer. Les TextIterTextIterTextIter : les itérateurs de texte possèdent de nombreuses méthodes qui seront décrites dans la section TextIterTextIter : les itérateurs de texte.

Les méthodes de TextBuffer basiques pour créer des TextIterTextIter : les itérateurs de texte sont :

 
Sélectionnez
1.
2.
3.
4.
5.
6.
7.
  iter = bufferdetexte.get_iter_at_offset(n)

  iter = bufferdetexte.get_iter_at_line(x)

  iter = bufferdetexte.get_iter_at_line_offset(x, n)

  iter = bufferdetexte.get_iter_at_mark(marque)

get_iter_at_offset() crée un itérateur juste après le ne caractère à partir du début du TextBuffer.

get_iter_at_line() crée un itérateur juste avant le premier caractère de la xe ligne.

get_iter_at_line_offset() crée un itérateur juste après le ne caractère de la xe ligne.

get_iter_at_mark() crée un itérateur à la même position que la TextMarkTextMark : les marques de texte marque.

Le méthode qui suit crée un ou plusieurs TextIterTextIter : les itérateurs de texte à des emplacements spécifiques du buffer :

 
Sélectionnez
1.
2.
3.
4.
5.
6.
7.
  iterdebut = bufferdetexte.get_start_iter()

  iterfin = bufferdetexte.get_end_iter()

  iterdebut, iterfin = bufferdetexte.get_bounds()

  debut, fin = bufferdetexte.get_selection_bounds()

get_start_iter() crée un itérateur juste avant le premier caractère du buffer.

get_end_iter() crée un itérateur juste après le dernier caractère du buffer.

get_bounds() crée un tuple de deux itérateurs respectivement situés juste avant le premier caractère et juste après le dernier caractère du buffer.

get_selection_bounds() crée un tuple de deux itérateurs aux mêmes positions que les marques insert et selection_bound du buffer.

13-3-3. Insérer, récupérer et supprimer du texte

Le texte contenu par un TextBuffer peut être défini avec la méthode suivante :

 
Sélectionnez
  bufferdetexte.set_text(texte)

Cette méthode remplace le contenu actuel de bufferdetexte par texte.

La méthode la plus générale pour insérer des caractères dans un TextBuffer est :

 
Sélectionnez
  bufferdetexte.insert(iter, texte)

où l'on insère le texte texte à l'emplacement de bufferdetexte spécifié par iter.

Si vous souhaitez simuler une insertion de texte par un utilisateur interactif, faites appel à la méthode suivante :

 
Sélectionnez
  resultat = bufferdetexte.insert_interactive(iter, texte, defaut_editable)

qui insérera texte dans le buffer, à la position spécifiée par iter, mais seulement si cette position est éditable (c'est-à-dire si elle ne porte pas de balise mentionnant que le texte est non éditable) et que la valeur de defaut_editable est TRUE. Le résultat indique si le texte a été inséré.

L'argument defaut_editable précise si un texte peut être édité dans le cas où il ne porte pas de balise le spécifiant ; defaut_editable est généralement déterminé par un appel à la méthode get_editable() du TextViewTextView : la zone de texte.

D'autres méthodes existent pour insérer du texte :

 
Sélectionnez
1.
2.
3.
4.
5.
6.
7.
  bufferdetexte.insert_at_cursor(texte)

  resultat = bufferdetexte.insert_at_cursor_interactive(texte, defaut_editable)

  bufferdetexte.insert_range(iter, debut, fin)

  resultat = bufferdetexte.insert_range_interactive(iter, debut, fin, defaut_editable)

insert_at_cursor() est une méthode pratique pour insérer du texte à l'emplacement courant du curseur (insert).

insert_range() copie le texte, les pixbufs et les balises compris entre les itérateurs debut et fin d'un TextBuffer (si ce TextBuffer n'est pas bufferdetexte, la table des balises doit être la même), puis colle le tout dans bufferdetexte à l'emplacement indiqué par iter.

Les versions interactives de ces méthodes opèrent de la même manière à la différence qu'elles n'insèrent la copie que si l'emplacement est éditable.

Enfin, en peut insérer du texte et lui appliquer des balises en même temps par l'intermédiaire des méthodes :

 
Sélectionnez
1.
2.
3.
  bufferdetexte.insert_with_tags(iter, texte, balise1, balise2, ...)
  
  bufferdetexte.insert_with_tags_by_name(iter, texte, nom_balise1, nom_balise2, ...)

insert_with_tags() insère le texte dans le bufferdetexte, à l'emplacement spécifié par l'iter, et lui applique les balises données.

insert_with_tags_by_name() fait la même chose mais permet de spécifier les balises en les nommant.

On peut effacer du texte d'un buffer avec les méthodes :

 
Sélectionnez
1.
2.
3.
  bufferdetexte.delete(debut, fin)
  
  resultat = bufferdetexte.delete_interactive(debut, fin, defaut_editable)

delete() supprime le texte compris entre les TextIterTextIter : les itérateurs de texte debut et fin de bufferdetexte.

delete_interactive() supprime tout texte éditable (déterminé comme tel par les balises de texte applicables et par l'argument defaut_editable) compris entre debut et fin.

Vous pouvez récupérer une copie du texte d'un TextBuffer grâce aux méthodes :

 
Sélectionnez
1.
2.
3.
  texte = bufferdetexte.get_text(debut, fin, include_hidden_chars=TRUE)

  texte = bufferdetexte.get_slice(debut, fin, include_hidden_chars=TRUE)

get_text() retourne une copie du texte du buffer compris entre debut et fin ; le texte non affiché est exclu si include_hidden_chars vaut FALSE. Les caractères représentant des images incrustées ou des widgets sont exclus.

get_slice() est identique à get_text() à la différence que le texte qu'elle retourne inclut un caractère 0xFFFC pour chaque image incrustée ou widget.

13-3-4. Créer et manipuler des TextMark

Les TextMarkTextMark : les marques de texte sont similaires aux TextIterTextIter : les itérateurs de texte en ceci qu'elles spécifient une position entre deux caractères d'un TextBuffer. Cependant, les TextMarkTextMarkTextMarkTextMark : les marques de texte maintiennent leur information de position même après modification du buffer. Les méthodes des TextMarkTextMarkTextMark : les marques de texte seront décrites plus loin dans la section TextMarkTextMark : les marques de texte.

Un buffer de texte contient deux marques inhérentes : la marque insert (insertion) et la marque selection_bound (fin de sélection). La marque insert est la position par défaut pour l'insertion de texte (le curseur). La marque selection_bound se combine avec la marque insert pour définir une sélection.

On peut retrouver ces deux marques en faisant appel aux méthodes suivantes :

 
Sélectionnez
1.
2.
3.
  marque_insert = bufferdetexte.get_insert()

  marque_selectionbound = bufferdetexte.get_selection_bound()

Les marques insert et selection_bound peuvent être placées simultanément à une position grâce à la méthode :

 
Sélectionnez
  bufferdetexte.place_cursor(emplacement)

emplacement est un TextIterTextIter : les itérateurs de texte qui indique la position. La méthode place_cursor() est nécessaire pour éviter de créer temporairement une sélection si les marques ont été déplacées individuellement.

On crée des TextMarkTextMark : les marques de texte avec la méthode :

 
Sélectionnez
  marque = bufferdetexte.create_mark(nom_marque, emplacement, left_gravity=FALSE)

nom_marque est le nom assigné à la marque créée (None pour une marque anonyme), emplacement est l'itérateur de texte indiquant la position de la marque dans le buffer, et left_gravity indique la situation de la marque après que du texte y aura été inséré (gauche si TRUE, droite si FALSE).

Une marque peut être déplacée dans le buffer avec les méthodes :

 
Sélectionnez
1.
2.
3.
  bufferdetexte.move_mark(marque, emplacement)

  bufferdetexte.move_mark_by_name(nom_marque, emplacement)

marque désigne la marque à déplacer. nom_marque spécifie le nom de la marque à déplacer. emplacement est un itérateur de texte indiquant la nouvelle position.

On peut supprimer une marque d'un buffer avec les méthodes :

 
Sélectionnez
1.
2.
3.
  bufferdetexte.delete_mark(marque)

  bufferdetexte.delete_mark_by_name(nom_marque)

On peut récupérer une marque par son nom avec la méthode :

 
Sélectionnez
  marque = bufferdetexte.get_mark(nom_marque)

13-3-5. Créer et appliquer des TextTag

Les TextTagLes TextTag contiennent un ou plusieurs attributs (comme les couleurs d'arrière-plan et de premier plan, la police, la possibilité d'édition) que l'on peut appliquer à une ou plusieurs portions du texte d'un buffer. Les attributs pouvant être spécifiés par une TextTagTextTagLes TextTag seront décrits dans la section TextTagLes TextTag.

La méthode suivante crée une TextTagLes TextTag avec des attributs et l'installe dans la TextTagTableLa TextTagTable d'un TextBuffer :

 
Sélectionnez
  balise = bufferdetexte.create_tag(name=None, attribut1=valeur1, attribut2=valeur2, ...)

name est soit une chaîne de caractères spécifiant le nom de la balise, soit None si la balise est anonyme. Les couples "attribut-valeur" déterminent les attributs de la balise. Reportez-vous à la section TextTagTextTagLes TextTag pour des informations concernant les attributs qui peuvent être définis par les propriétés d'une TextTagLes TextTag.

Une balise peut être appliquée à une portion du texte d'un buffer par la méthode suivante :

 
Sélectionnez
1.
2.
3.
  bufferdetexte.apply_tag(balise, debut, fin)

  bufferdetexte.apply_tag_by_name(nom_balise, debut, fin)

balise est la balise à appliquer au texte, nom_balise le nom de la balise, et debut et fin des itérateurs de texte qui indiquent la portion de texte à laquelle la balise doit être appliquée.

On peut retirer une balise d'une portion de texte en utilisant les méthodes suivantes :

 
Sélectionnez
1.
2.
3.
  bufferdetexte.remove_tag(balise, debut, fin)

  bufferdetexte.remove_tag_by_name(nom_balise, debut, fin)

Pour retirer toutes les balises d'une portion de texte, on utilisera :

 
Sélectionnez
  bufferdetexte.remove_all_tags(debut, fin)

13-3-6. Insérer des images et des widgets

En plus du texte, un TextBuffer peut contenir des images pixbuf et un point d'ancrage pour widgets. Ce point d'ancrage sert à ajouter un widget à une TextViewTextViewTextView : la zone de texte. Un widget différent peut être ajouté dans chaque TextViewTextView : la zone de texte qui affiche un buffer contenant un point d'ancrage.

On peut insérer une image pixbuf avec la méthode suivante :

 
Sélectionnez
  bufferdetexte.insert_pixbuf(iter, pixbuf)

dans laquelle iter précise l'emplacement du buffer où insérer l'image pixbuf. Cette image comptera pour un caractère et sera représentée par le caractère Unicode "0xFFFC" dans le texte retourné par la méthode get_slice() (il ne figurera pas dans celui retourné par get_text()).

On peut insérer un widget GTK+ dans une TextViewTextView : la zone de texte, ` un emplacement du buffer spécifié par un TextChildAnchor (point d'ancrage pour enfant). Tout comme une image pixbuf, le TextChildAnchor comptera pour un caractère représenté par "0xFFFC".

Le moyen le plus commode de créer et d'insérer un TextChildAnchor est la méthode suivante :

 
Sélectionnez
  ancrage = bufferdetexte.create_child_anchor(iter)

iter est l'emplacement destiné à recevoir le point d'ancrage.

Mais on peut aussi créer et insérer le TextChildAnchor en deux temps ainsi :

 
Sélectionnez
1.
2.
3.
  ancrage = gtk.TextChildAnchor()

  bufferdetexte.insert_child_anchor(iter, ancrage)

Puis l'on peut ajouter le widget à la TextViewTextView : la zone de texte, au point d'ancrage, grâce à la méthode suivante :

 
Sélectionnez
  zonedetexte.add_child_at_anchor(widget_enfant, ancrage)

La méthode qui suit permet de récupérer la liste des widgets attachés à un point d'ancrage :

 
Sélectionnez
  liste_widgets = ancrage.get_widgets()

On peut également ajouter un widget à une TextViewTextView : la zone de texte en utilisant cette méthode :

 
Sélectionnez
  zonedetexte.add_child_in_window(widget_enfant, fenetre, position_x, position_y)

où le widget_enfant sera placé dans la fenêtre fenetre à la positon spécifiée par position_x et position_y. fenetre indique laquelle des fenêtres qui composent la TextViewTextView : la zone de texte doit recevoir le widget enfant :

 
Sélectionnez
1.
2.
3.
4.
5.
6.
  gtk.TEXT_WINDOW_TOP       # fenêtre supérieure
  gtk.TEXT_WINDOW_BOTTOM    # fenêtre inférieure
  gtk.TEXT_WINDOW_LEFT      # fenêtre de gauche
  gtk.TEXT_WINDOW_RIGHT     # fenêtre de droite
  gtk.TEXT_WINDOW_TEXT      # fenêtre du texte
  gtk.TEXT_WINDOW_WIDGET    # fenêtre du widget

13-4. TextIter : les itérateurs de texte

Les TextIter représentent une position entre deux caractères d'un TextBufferTextBufferTextBuffer : le buffer de texte. Ils sont généralement créés par une méthode de TextBufferTextBuffer : le buffer de texte et sont invalidés lorsque le nombre de caractères de ce dernier est modifié (excepté le TextIter utilisé pour l'insertion ou la suppression). Insérer ou supprimer des images pixbuf ou des points d'ancrage consiste aussi en une modification du buffer, et invalide par conséquent les TextIter.

L'objet TextIter possède un grand nombre de méthodes. Celles-ci sont groupées par fonction similaire dans les sections suivantes.

13-4-1. Récupérer les attributs d'un TextIter

On peut récupérer le TextBuffer qui contient le TextIter iter avec la méthode :

 
Sélectionnez
  buffer = iter.get_buffer()

Les méthodes suivantes permettent de récupérer la localisation du TextIter iter dans le TextBufferTextBuffer : le buffer de texte :

 
Sélectionnez
1.
2.
3.
4.
5.
6.
7.
  num_car = iter.get_offset()            # renvoie la position de iter en partant du début du buffer

  num_ligne = iter.get_line()            # renvoie le numéro de la ligne de iter

  num_car_ligne = iter.get_line_offset()    # renvoie la position de iter en partant du début de la ligne

  nbr_car_ligne = iter.get_chars_in_line()    # renvoie le nombre de caractères dans la ligne de iter

13-4-2. Récupérer les attributs d'un texte portant un TextIter

Le PangoLanguage utilisé à un emplacement du buffer portant un itérateur peut s'obtenir avec la méthode suivante :

 
Sélectionnez
  langage = iter.get_language()

Plus généralement, on fera appel à la méthode qui suit pour récupérer les attributs d'un texte à une position portant un TextIter :

 
Sélectionnez
  resultat = iter.get_attributes(valeurs)

La variable resultat indiquera si les valeurs fournies en argument (qui doivent être des objets TextAttributes) ont été modifiées. On obtient ces valeurs par l'intermédiaire de la méthode de TextViewTextView : la zone de texte suivante :

 
Sélectionnez
  valeurs = zonedetexte.get_default_attributes()

zonedetexte est la TextViewTextView : la zone de texte en question.

On peut accéder aux attributs suivants à partir d'un objet TextAttributes (non implémenté dans PyGTK <= 1.99.15) :

bg_color

couleur de l'arrière-plan

fg_color

couleur du premier plan

bg_stipple

bitmap à utiliser comme masque pour l'arrière-plan

fg_stipple

bitmap à utiliser comme masque pour le premier plan

rise

décalage du texte au-dessus de la ligne de base

underline

style de soulignement

strikethrough

texte barré

draw_bg

TRUE si des balises affectent le dessin de l'arrière-plan

justification

type d'alignement

direction

direction du texte

font

PangoFontDescription utilisée

font_scale

échelle de la police utilisée

left_margin

largeur de la marge de gauche

right_margin

largeur de la marge de droite

pixels_above_lines

espacement en pixels au-dessus des paragraphes

pixels_below_lines

espacement en pixels au-dessous des paragraphes

pixels_inside_wrap

espacement en pixels entre les lignes coupées dans un paragraphe

tabs

PangoTabArray utilisé

wrap_mode

mode de retour à la ligne automatique utilisé

language

PangoLanguage utilisé

invisible

texte invisible (non implémenté dans GTK+ 2.0)

bg_full_height

hauteur de l'arrière-plan par rapport à la ligne

editable

possibilité d'édition du texte

realized

texte réalisé

pad1

 

pad2

 

pad3

 

pad4

 

13-4-3. Copier un TextIter

Il est possible de dupliquer un TextIter grâce à la méthode :

 
Sélectionnez
  copie_iter = iter.copy()

13-4-4. Récupérer du texte et des objets

On peut récupérer différentes quantités de texte et d'objets de TextBufferTextBuffer : le buffer de texte en utilisant les méthodes suivantes :

 
Sélectionnez
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
  caract = iter.get_char()            # renvoie le caractère qui suit iter (ou 0 si l'on est à la fin du buffer)

  texte = debut.get_slice(fin)            # renvoie le texte compris entre les itérateurs debut et fin

  texte = debut.get_text(fin)            # renvoie le texte compris entre les itérateurs debut et fin

  pixbuf = iter.get_pixbuf()            # renvoie l'image pixbuf située à l'itérateur iter (ou None)

  ancrage = iter.get_child_anchor()        # renvoie le point d'ancrage situé à l'itérateur iter(ou None)

  liste_marques = iter.get_marks()        # renvoie une liste de marques

  liste_balises = iter.get_toggled_tags()    # renvoie une liste de balises activées ou désactivées

  liste_balises = iter.get_tags()        # renvoie une liste de balises par priorités

13-4-5. Vérifier les balises à une position de TextIter

Les méthodes suivantes permettent de vérifier certaines caractéristiques des balises se trouvant à une position de TextIter :

 
Sélectionnez
1.
2.
3.
4.
5.
6.
7.
  resultat = iter.begins_tag(tag=None)    # renvoie TRUE si tag s'active à l'emplacement iter

  resultat = iter.ends_tag(tag=None)    # renvoie TRUE si tag se désactive à l'emplacement iter

  resultat = iter.toggles_tag(tag=None)    # renvoie TRUE si tag s'active ou se désactive à l'emplacement iter

  resultat = iter.has_tag(tag)        # renvoie TRUE si la portion de texte contenant iter est balisée par tag

Ces méthodes renvoient TRUE si la balise tag à la position iter remplit la condition. Si l'argument tag vaut None aux trois premières méthodes, le résultat sera TRUE si n'importe quelle balise remplit la condition à la position iter.

Les deux méthodes qui suivent indiquent si le texte situé à la position spécifiée par le TextIter est éditable ou accepte une insertion de texte :

 
Sélectionnez
1.
2.
3.
  resultat = iter.editable()

  resultat = iter.can_insert(defaut_editable)

La méthode editable() indique si l'itérateur iter se situe dans une portion de texte éditable. La méthode can_insert() indique si l'on peut insérer du texte à l'emplacement spécifié par iter, en prenant en compte la possibilité d'édition par défaut de la TextViewTextView : la zone de texte, du TextBufferTextBuffer : le buffer de texte et des balises applicables. L'argument defaut_editable est généralement déterminé par un appel à la méthode de TextViewTextView : la zone de texte :

 
Sélectionnez
  defaut_editable = zonedetexte.get_editable()

zonedetexte est la TextViewTextView : la zone de texte.

On peut savoir si deux TextIter sont équivalents grâce à la méthode :

 
Sélectionnez
  egalite = iter1.equal(iter2)

La méthode suivante permet de comparer deux TextIter :

 
Sélectionnez
  resultat = iterA.compare(iterB)

resultat aura pour valeur : -1 si iterA est inférieur à iterB ; 0 si iterA égale iterB ; et 1 si iterA est supérieur à iterB.

Pour savoir si un TextIter se trouve entre deux TextIter donnés, utilisez la méthode :

 
Sélectionnez
  resultat = iter.in_range(debut, fin)

resultat vaudra TRUE si iter est situé entre debut et fin. Attention, debut et fin doivent être donnés dans l'ordre croissant ! Ceci peut être assuré par la méthode :

 
Sélectionnez
  iterA.order(iterB)

qui réorganise les positions des TextIter de sorte que iterA soit avant iterB.

13-4-6. Vérifier la position dans le texte

On peut déterminer la position d'un TextIter par rapport au texte d'un TextBufferTextBuffer : le buffer de texte grâce aux méthodes suivantes :

 
Sélectionnez
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
  resultat = iter.starts_word()            # iter commence un mot

  resultat = iter.ends_word()            # iter termine un mot

  resultat = iter.inside_word()            # iter est à l'intérieur d'un mot

  resultat = iter.starts_sentence()        # iter commence une phrase

  resultat = iter.ends_sentence()        # iter termine une phrase

  resultat = iter.inside_sentence()        # iter est à l'intérieur d'une phrase

  resultat = starts_line()            # iter commence une ligne

  resultat = iter.ends_line()            # iter termine une ligne

resultat renvoie TRUE si le TextIter est à la position donnée. La définition de "mot" et "phrase" dépend du langage utilisé à la position du TextIter. Quant à la ligne, il s'agit d'un ensemble de phrases s'apparentant à un paragraphe.

La méthode suivante permet de déterminer si un TextIter se situe au début ou à la fin du TextBufferTextBuffer : le buffer de texte :

 
Sélectionnez
1.
2.
3.
  resultat = iter.is_start()

  resultat = iter.is_end()

resultat vaudra TRUE si le TextIter est situé au début ou à la fin du TextBufferTextBuffer : le buffer de texte.

Du fait qu'un TextBufferTextBuffer : le buffer de texte peut contenir des groupe de caractères s'affichant comme une seule position de curseur (par exemple, un retour chariot + saut de ligne, ou une lettre + marque d'accent), il est possible qu'un TextIter soit à un emplacement ne représentant pas une position de curseur possible. Dans un tel cas, la méthode suivante renverrait FALSE :

 
Sélectionnez
  resultat = iter.is_cursor_position()

13-4-7. Se déplacer dans le texte

On peut déplacer les TextIter dans un TextBufferTextBuffer : le buffer de texte par sauts de différents éléments de texte. La définition de ces éléments de texte est fixée par le PangoLanguage utilisé à l'emplacement du TextIter. Les méthodes basiques sont :

 
Sélectionnez
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
  resultat = iter.forward_char()            # avancer d'un caractère

  resultat = iter.backward_char()            # reculer d'un caractère

  resultat = iter.forward_word_end()            # avancer à la fin du mot

  resultat = iter.backward_word_start()            # reculer au début du mot

  resultat = iter.forward_sentence_end()        # avancer à la fin de la phrase

  resultat = iter.backward_sentence_start()        # reculer à au début de la phrase

  resultat = iter.forward_line()            # avancer au début de la prochaine ligne

  resultat = iter.backward_line()            # reculer au début de la ligne précédente

  resultat = iter.forward_to_line_end()            # avancer à la fin de la ligne

  resultat = iter.forward_cursor_position()        # avancer à la prochaine position de curseur

  resultat = iter.backward_cursor_position()        # reculer à la position de curseur précédente

resultat vaut TRUE si le TextIter a été déplacé et FALSE s'il se trouve au début ou à la fin du TextBufferTextBuffer : le buffer de texte.

Toutes les méthodes ci-dessus (hormis forward_to_line_end()) ont un équivalent avec argument. Ce dernier est un nombre (positif ou négatif) indiquant de combien d'unités doit se déplacer le TextIter :

 
Sélectionnez
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
  resultat = iter.forward_chars(combien)

  resultat = iter.backward_chars(combien)

  resultat = iter.forward_word_ends(combien)

  resultat = iter.backward_word_starts(combien)

  resultat = iter.forward_sentence_ends(combien)

  resultat = iter.backward_sentence_starts(combien)

  resultat = iter.forward_lines(combien)

  resultat = iter.backward_lines(combien)

  resultat = iter.forward_cursor_positions(combien)

  resultat = iter.backward_cursor_positions(combien)

13-4-8. Se déplacer à un emplacement spécifique

Un TextIter peut être déplacé à un emplacement spécifique du TextBufferTextBuffer : le buffer de texte avec les méthodes suivantes :

 
Sélectionnez
1.
2.
3.
4.
5.
6.
7.
  iter.set_offset(n)        # déplace iter juste après le nième caractère du buffer

  iter.set_line(x)        # déplace iter au début de la xi ligne

  iter.set_line_offset(n)    # déplace iter juste après le nième caractère de sa ligne

  iter.forward_to_end()        # déplace iter à la dernière position du buffer

Un TextIter peut également être déplacé vers un emplacement où une balise s'active ou se désactive, et ce, grâce à la méthode suivante :

 
Sélectionnez
1.
2.
3.
  resultat = iter.forward_to_tag_toggle(balise)

  resultat = iter.backward_to_tag_toggle(balise)

resultat vaudra TRUE si le TextIter a été déplacé vers une nouvelle position où balise s'active ou se désactive. Si balise vaut None, la méthode déplacera TextIter vers la prochaine position où n'importe quelle balise s'active ou se désactive.

13-4-9. Rechercher du texte

La méthode suivante permet de rechercher une chaîne de caractères dans un TextBufferTextBuffer : le buffer de texte :

 
Sélectionnez
1.
2.
3.
  debut_resultat, fin_resultat = iter.forward_search(chaine, drapeaux, limit=None)

  debut_resultat, fin_resultat = iter.backward_search(chaine, drapeaux, limit=None)

La méthode renvoie un tuple contenant deux TextIter. Ces derniers indiquent respectivement la position du premier caractère du résultat et celle du premier caractère suivant ce résultat. chaine est la chaîne de caractères à localiser. Les drapeaux modifient les paramètres de la recherche ; il peuvent prendre comme valeurs :

 
Sélectionnez
1.
2.
3.
  gtk.TEXT_SEARCH_VISIBLE_ONLY        # les caractères invisibles seront ignorés

  gtk.TEXT_SEARCH_TEXT_ONLY        # les images pixbuf et les points d'ancrages seront ignorés

limit est un TextIter facultatif qui limite la recherche au texte le précédant.

13-5. TextMark : les marques de texte

Une TextMark indique une position entre deux caractères d'un TextBufferTextBufferTextBufferTextBuffer : le buffer de texte, position qui sera préservée en cas de modification du buffer. Pour créer, déplacer, ou supprimer des TextMark, on utilise les méthodes de TextBufferTextBufferTextBuffer : le buffer de texte décrites dans la section TextBufferTextBuffer : le buffer de texte.

Un TextBufferTextBuffer : le buffer de texte possède deux TextMark inhérentes, nommées insert et selection_bound, qui font respectivement référence à la position du point d'insertion et à celle de la fin de la sélection (elles peuvent désigner la même position).

On peut récupérer le nom d'une TextMark avec la méthode :

 
Sélectionnez
  nom_marque = marque.get_name()

Par défaut, seule la marque insert est visible. La visibilité d'une marque (une barre verticale) peut être définie et récupérée en utilisant respectivement les méthodes suivantes :

 
Sélectionnez
1.
2.
3.
  marque.set_visible(choix)

  visible = marque.get_visible()

visible vaut TRUE si la marque est visible.

On récupère le TextBufferTextBuffer : le buffer de texte qui contient une TextMark donnée avec la méthode :

 
Sélectionnez
  buffer = marque.get_buffer()

On peut savoir si une TextMark a été supprimée en faisant appel à la méthode :

 
Sélectionnez
  marque_suppr = marque.get_deleted()

La gravité d'une TextMark peut être récupérée par la méthode :

 
Sélectionnez
  gravite = marque.get_left_gravity()

La gravité d'une marque indique la situation de celle-ci après que l'on aura inséré du texte à sa position. Si la gravite vaut TRUE, la marque sera à gauche du texte inséré ; si elle vaut FALSE, elle sera à droite.

13-6. TextTag et TextTagTable : les balises de texte

Les TextTag (balises de texte) spécifient les attributs qui peuvent être appliqués à une portion du texte d'un TextBufferTextBufferTextBufferTextBufferTextBuffer : le buffer de texte. Chaque TextBufferTextBufferTextBufferTextBuffer : le buffer de texte a une TextTagTable (table des balises de texte) qui contient les balises pouvant être appliquées à l'intérieur du TextBufferTextBufferTextBuffer : le buffer de texte. Les TextTagTables peuvent être partagées par plusieurs TextBufferTextBuffer : le buffer de texte, offrant par là une meilleure homogénéité des styles de texte.

13-6-1. Les TextTag

Les TextTag peuvent porter un nom ou bien être anonymes. On crée une TextTag en utilisant la fonction :

 
Sélectionnez
  balise = gtk.TextTag(name=None)

Si aucun name (nom) n'est donné ou s'il vaut None, la balise sera anonyme. Il peut être plus commode de créer des TextTag avec la méthode de TextBufferTextBuffer : le buffer de texte create_tag(), celle-ci permettant aussi de spécifier les attributs de la balise et de l'ajouter à la table des balises du buffer (cf. la section TextBufferTextBuffer : le buffer de texte)

Les attributs que peut porter une TextTag sont :

name

Lecture / Écriture

Nom de la balise de texte. None si anonyme.

background

Écriture

Couleur de l'arrière-plan donnée sous forme de chaîne de caractères.

foreground

Écriture

Couleur du premier plan donnée sous forme de chaîne de caractères.

background_gdk

Lecture / Écriture

Couleur de l'arrière-plan donnée sous forme de GdkColor.

foreground_gdk

Lecture / Écriture

Couleur du premier plan donnée sous forme de GdkColor.

background_stipple

Lecture / Écriture

Bitmap à utiliser comme masque lorsque l'on dessine le texte d'arrière-plan.

foreground_stipple

Lecture / Écriture

Bitmap à utiliser comme masque lorsque l'on dessine le texte du premier plan.

font

Lecture / Écriture

Description de la police donnée sous forme de chaîne de caractères. Ex. : "Sans Italic 12".

font_desc

Lecture / Écriture

Description de la police donnée sous forme de PangoFontDescription.

family

Lecture / Écriture

Nom de la famille de la police. Ex. : Sans, Helvetica, Times, Monospace.

style

Lecture / Écriture

Style de la police donné sous forme de PangoStyle. Ex. : pango.STYLE_ITALIC.

variant

Lecture / Écriture

Variante de police donnée sous forme de PangoVariant. Ex. : pango.VARIANT_SMALL_CAPS.

weight

Lecture / Écriture

Épaisseur de police donnée sous forme d'entier (voir aussi les valeurs prédéfinies dans PangoWeight, ex. : pango.WEIGHT_BOLD).

stretch

Lecture / Écriture

Étirement de la police donné sous forme de PangoStretch. Ex. : pango.STRETCH_CONDENSED.

size

Lecture / Écriture

Taille de la police en unités Pango.

size_points

Lecture / Écriture

Taille de la police en points.

scale

Lecture / Écriture

Taille de la police donnée sous forme de facteur d'échelle par rapport à la taille de la police par défaut. Recommandé, car très bonne adaptation aux changements de thème, etc. Pango possède quelques échelles prédéfinies, comme pango.SCALE_X_LARGE.

pixels_above_lines

Lecture / Écriture

Espacement au-dessus des paragraphes en pixels.

pixels_below_lines

Lecture / Écriture

Espacement au-dessous des paragraphes en pixels.

pixels_inside_wrap

Lecture / Écriture

Espacement entre les lignes des paragraphes en pixels.

editable

Lecture / Écriture

Possibilité pour l'utilisateur d'éditer le texte.

wrap_mode

Lecture / Écriture

Mode de retour à la ligne automatique (après le dernier mot de la ligne, après le dernier caractère de la ligne, ou désactivé).

justification

Lecture / Écriture

Alignement à gauche, à droite, ou centré.

direction

Lecture / Écriture

Direction du texte (de gauche à droite ou de droite à gauche).

left_margin

Lecture / Écriture

Largeur de la marge de gauche en pixels.

indent

Lecture / Écriture

Indentation du paragraphe en pixels.

strikethrough

Lecture / Écriture

Indique si le texte doit être barré.

right_margin

Lecture / Écriture

Largeur de la marge de droite en pixels.

underline

Lecture / Écriture

Style de soulignement.

rise

Lecture / Écriture

Décalage du texte par rapport à la ligne de base (au-dessus s'il est positif, au-dessous si négatif) en pixels.

background_full_height

Lecture / Écriture

Indique si la couleur d'arrière-plan doit remplir toute la hauteur de la ligne ou seulement la hauteur des caractères balisés.

language

Lecture / Écriture

La langue du texte, donnée sous forme de code ISO. Ceci peut aider Pango pour le rendu du texte. Si vous ne comprenez pas ce paramètre, vous n'en avez probablement pas besoin.

tabs

Lecture / Écriture

Tabulations personnalisées.

invisible

Lecture / Écriture

Visibilité du texte (non implémentée dans GTK 2.0)

On peut définir les attributs d'une balise avec la méthode :

 
Sélectionnez
  balise.set_property(nom_attr, valeur)

dans laquelle nom_attr est une chaîne contenant le nom de l'attribut et valeur la valeur qui doit lui être affectée.

De la même manière, on peut récupérer la valeur de l'attribut avec la méthode :

 
Sélectionnez
  valeur = balise.get_property(nom_attr)

Du fait qu'une balise ne contient pas forcément tous les attributs précédemment cités, un certain nombre de propriétés booléennes ont été créées, qui permettent simplement de savoir si la balise est porteuse ou pas de tel attribut :

background_set

Lecture / Écriture

foreground_set

Lecture / Écriture

background_stipple_set

Lecture / Écriture

foreground_stipple_set

Lecture / Écriture

family_set

Lecture / Écriture

style_set

Lecture / Écriture

variant_set

Lecture / Écriture

weight_set

Lecture / Écriture

stretch_set

Lecture / Écriture

size_set

Lecture / Écriture

scale_set

Lecture / Écriture

pixels_above_lines_set

Lecture / Écriture

pixels_below_lines_set

Lecture / Écriture

pixels_inside_wrap_set

Lecture / Écriture

editable_set

Lecture / Écriture

wrap_mode_set

Lecture / Écriture

justification_set

Lecture / Écriture

direction_set

Lecture / Écriture

left_margin_set

Lecture / Écriture

indent_set

Lecture / Écriture

strikethrough_set

Lecture / Écriture

right_margin_set

Lecture / Écriture

underline_set

Lecture / Écriture

rise_set

Lecture / Écriture

background_full_height_set

Lecture / Écriture

language_set

Lecture / Écriture

tabs_set

Lecture / Écriture

invisible_set

Lecture / Écriture

Pour récupérer un attribut d'une balise, vous devez donc d'abord vérifier s'il est bien défini dans cette balise. Par exemple, pour obtenir un attribut valide d'alignement, vous pourriez procéder comme suit :

 
Sélectionnez
  if balise.get_property("justification_set"):
    alignement = balise.get_property("justification")

Par défaut, la priorité des balises correspond à l'ordre dans lequel elles sont ajoutées à la TextTagTableLa TextTagTable. La balise qui a la plus haute priorité prend l'avantage dans le cas où plusieurs tentent de définir le même attribut pour une portion de texte. La priorité se récupère et se définit avec les méthodes suivantes :

 
Sélectionnez
1.
2.
3.
  priorite = balise.get_priority()

  balise.set_priority(priorite)

La priorité d'une balise doit être comprise entre 0 et la taille de la TextTagTableLa TextTagTable moins 1.

13-6-2. La TextTagTable

Par défaut, une TextTagTable est créée avec la création d'un TextBufferTextBuffer : le buffer de texte. Mais elle peut tout aussi bien être créée par la fonction :

 
Sélectionnez
  table = TextTagTable()

On ajoute une TextTagLes TextTag a une TextTagTable avec la méthode :

 
Sélectionnez
  table.add(balise)

La balise ne doit pas déjà être dans la table et ne doit pas porter le même nom qu'une balise s'y trouvant déjà.

On peut chercher une TextTagLes TextTag dans une TextTagTable en utilisant la méthode :

 
Sélectionnez
  balise = table.lookup(nom)

La méthode renvoie la balise qui porte ce nom dans la table, ou None si aucune balise ne porte ce nom.

On peut retirer une TextTagLes TextTag d'une TextTagTable avec la méthode :

 
Sélectionnez
  table.remove(balise)

Enfin, la taille d'une TextTagTable peut être récupérée par :

 
Sélectionnez
  taille_table = table.get_size()

13-7. Un exemple de TextView

Le programme testtexte.py (dérivé du programme testtext.c inclus dans la distribution GTK+ 2.0.x) montre un exemple d'utilisation du widget TextViewTextView : la zone de texte et des objets qui lui sont associés : TextBufferTextBuffer : le buffer de texte, TextIterTextIter : les itérateurs de texte, TextMarkTextMark : les marques de texte, TextTagLes TextTag, et TextTagTableLa TextTagTable. La Figure 13.2 illustre le résultat :

Image non disponible
Figure 13.2. Exemple de TextView

En plus de TestTexte, la classe principale de l'application, le programme testtexte.py définit plusieurs autres classes :

  • la classe Buffer, aux lignes 102 à 499, est une sous-classe dérivée de gtk.TextBuffer. Elle apporte les fonctions d'édition du buffer utilisées par les objets Fenetre ;
  • la classe Fenetre, de la ligne 501 à la ligne 1129, est une sous-classe dérivée de gtk.Window. Elle englobe une gtk.TextView, qui utilise un objet Buffer au lieu d'un gtk.TextBuffer. Elle fournit une fenêtre équipée d'une barre de menu, et y affiche le contenu d'un objet Buffer ;
  • la classe SelectionFichier des lignes 76 à 100, est une sous-classe dérivée de gtk.FileSelection, qui permet de sélectionner des noms de fichiers pour le contenu du Buffer ;
  • Enfin, la classe Pile crée des piles assez simples.

L'alternance des couleurs est implémentée en utilisant des balises que l'on applique à une portion de texte d'un buffer. Ces balises sont créées aux lignes 112 à 118 par la méthode __init__(). Puis, la méthode change_appliquer_couleurs() se charge de les appliquer à une portion de texte, et ce tous les deux caractères (lignes 766 à 787). Les lignes 205 à 242 fournissent les méthodes (cycle_couleurs(), couleurs() et alterner_couleurs()) qui produisent l'alternance une fois celle-ci activée. Cette activation s'effectue à la ligne 223 en définissant la propriété foreground_gdk de chaque balise de balises_couleurs (ce qui définit par la même occasion la propriété foreground_set). On désactive cette même alternance de couleurs en donnant la valeur FALSE à la propriété foreground_set (ligne 225). On alterne les couleurs périodiquement en modifiant la variable teinte_depart (ligne 240).

Lorsque la commande Test->Exemple est sélectionnée, un nouveau Buffer est rempli avec un exemple de texte (il s'agit de la méthode remplir_buffer_exmpl() des lignes 305 à 375). Le buffer contient alors du texte de différentes couleurs, styles et langages, ainsi que des images pixbuf. La méthode init_balises() des lignes 263 à 303 définit un ensemble de TextTagLes TextTag qui sont utilisées par le texte d'exemple. Le signal "event" (évènement) de ces balises est connecté à la méthode gest_evnmt_balises (lignes 243 à 259) pour illustrer la capture de différents évènements (mouvement, clics).

On règle le type de retour à la ligne automatique de la TextViewTextViewTextView : la zone de texte sur WRAP_WORD (ligne 583) et on affiche ses fenêtres de bordure en fixant leurs dimensions (590-591 et 599-600). Les fenêtres de bordure supérieure et inférieure serviront à afficher les positions des tabulations lorsque les tabulations personnalisées sont sélectionnées, et les fenêtres latérales à afficher les numéros des lignes. Les fenêtres de bordures sont rafraîchies lorsqu'un signal "expose-event" (besoin de réaffichage) est reçu par la TextViewTextView : la zone de texte (lignes 593 et 602). La méthode affichage_num_lignes() (lignes 1082 à 1119) détermine si le signal "expose-event" provient d'une des fenêtres de bordure latérales, auquel cas elle calcule la taille de la zone à réafficher. Puis l'emplacement du début de la ligne ainsi que le numéro de chaque ligne de cette zone sont calculés par la méthode recup_lignes() (lignes 1060-1080). Les numéros de ligne sont alors affichés dans la fenêtre de bordure, à l'emplacement adéquat (transformé par la ligne 1112).

Les emplacements des tabulations personnalisées apparaissent dans les fenêtres supérieure et inférieure (lignes 1016 à 1058), mais seulement lorsque le curseur se situe dans une portion de texte portant l'attribut "tabulations personnalisées". Pour vérifier cette condition, on traite le signal "mark-set" (marque définie) avec la méthode rappel_mvt_curseur() (lignes 1002 à 1014), qui invalide ces deux fenêtres si insert est la marque définie.

Des objets mobiles sont ajoutés à une Fenetre par la méthode ajouter_enfants() (lignes 895 à 902), qui appelle la méthode ajouter_enfants_deplace() (lignes 877-893). Les enfants sont des gtk.Label que l'on peut faire glisser à l'intérieur des différentes fenêtres composant une TextViewTextView : la zone de texte.

De la même manière, des widgets sont insérés dans le buffer ainsi que dans les différentes fenêtres d'un objet Fenetre en faisant appel à la méthode ajouter_enfants_focus (lignes 904 à 952).


précédentsommairesuivant

Vous avez aimé ce tutoriel ? Alors partagez-le en cliquant sur les boutons suivants : Viadeo Twitter Facebook Share on Google+   

  

Copyright © 2005 John Finlay. Aucune reproduction, même partielle, ne peut être faite de ce site ni de l'ensemble de son contenu : textes, documents, images, etc. sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu'à trois ans de prison et jusqu'à 300 000 € de dommages et intérêts.