Les TreeViewColumn et les
CellRenderer travaillent ensemble pour afficher une
colonne de données dans un TreeView. Le
TreeViewColumn fournit un en-tête de colonne ainsi
qu'un espace vertical que les CellRenderer utiliseront
pour afficher une partie des données stockées dans le modèle du
TreeView. Un CellRenderer prend
en charge l'affichage des données de chaque ligne et colonne dans l'espace
offert par le TreeViewColumn. Un
TreeViewColumn peut contenir plusieurs
CellRenderer pour afficher les lignes comme des
HBox. On combine par exemple assez fréquemment un
CellRendererPixbuf et un
CellRendererText dans la même colonne.
L'application de chaque CellRenderer est
indiquée avec une couleur d'arrière-plan : jaune pour le
CellRendererPixbuf, cyan pour le
CellRendererText, et rose pour l'autre
CellRendererText. Notez que le
CellRendererPixbuf et le premier
CellRendererText sont dans la même colonne, dont l'en-tête
est "Pixbuf and Text". La couleur d'arrière-plan du
CellRendererText qui affiche "Imprime un fichier" est la
couleur par défaut afin de montrer la zone d'application sur une seule ligne.
Le type de CellRenderer dont on a besoin dépend du type
d'affichage attendu pour les données du modèle ; PyGTK dispose de trois
CellRenderer prédéfinis :
CellRendererPixbuf
affiche des images pixbuf créées par le programme ou disponibles dans
le stock de PyGTK.
CellRendererText
affiche des chaines de caractères, ainsi que des nombres pouvant être
convertis en chaines de caractères (incluant les entiers, les réels, les booléens).
CellRendererToggle
affiche une valeur booléenne sous la forme d'un bouton à bascule ou
d'un bouton radio.
14.4.3. Les propriétés des CellRenderer
Les propriétés d'un CellRenderer déterminent la
manière dont les données doivent être affichées :
"mode"
Lecture-écriture
La possibilité ou non d'éditer le
CellRenderer. Peut être :
gtk.CELL_RENDERER_MODE_INERT,
gtk.CELL_RENDERER_MODE_ACTIVATABLE ou
gtk.CELL_RENDERER_MODE_EDITABLE
"visible"
Lecture-écriture
Si elle vaut TRUE, la cellule est affichée.
"xalign"
Lecture-écriture
La fraction (entre 0.0 et 1.0) d'espace vide devant
se situer dans la partie gauche de la cellule.
"yalign"
Lecture-écriture
La fraction (entre 0.0 et 1.0) d'espace vide devant
se situer dans la partie supérieure de la cellule.
"xpad"
Lecture-écriture
La quantité d'espacement à gauche et à droite de la cellule.
"ypad"
Read-Write
La quantité d'espacement au-dessus et au-dessous de la cellule.
"width"
Lecture-écriture
La largeur fixe de la cellule.
"height"
Lecture-écriture
La hauteur fixe de la cellule.
"is-expander"
Lecture-écriture
Si elle vaut TRUE, la ligne a des lignes
filles.
"is-expanded"
Lecture-écriture
Si elle vaut TRUE, la ligne a des lignes
filles et est développée afin de montrer celles-ci.
"cell-background"
Écriture
La couleur d'arrière-plan de la cellule sous la forme d'une
chaine de caractères.
"cell-background-gdk"
Lecture-écriture
La couleur d'arrière-plan de la cellule sous la forme d'une
gtk.gdk.Color.
"cell-background-set"
Lecture-écriture
Si elle vaut TRUE, la couleur d'arrière-plan
de la cellule est définie par ce CellRenderer.
Les propriétés ci-dessus sont disponibles pour toutes les sous-classes de
CellRenderer. Chaque type de
CellRenderer dispose en plus de ses propres propriétés.
Le CellRendererPixbuf a les propriétés suivantes :
"pixbuf"
Lecture-écriture
La pixbuf à afficher - invalidée par "stock-id".
"pixbuf-expander-open"
Lecture-écriture
Pixbuf pour le symbole de développement ouvert.
"pixbuf-expander-closed"
Lecture-écriture
Pixbuf pour le symbole de développement fermé.
"stock-id"
Lecture-écriture
L'icône du stock de PyGTK à afficher.
"stock-size"
Lecture-écriture
La taille de l'icône à afficher.
"stock-detail"
Lecture-écriture
Détail d'affichage à transmettre au moteur de thèmes.
Le CellRendererText possède un grand nombre de
propriétés donnant pour la plupart des indications stylistiques :
"text"
Lecture-écriture
Texte à afficher.
"markup"
Lecture-écriture
Texte balisé à afficher.
"attributes"
Lecture-écriture
Une liste d'attributs de style à appliquer au texte
du CellRenderer.
"background"
Écriture
Couleur d'arrière-plan, sous la forme d'une chaine de caractères.
"foreground"
Écriture
Couleur d'avant-plan, sous la forme d'une chaine de caractères.
"background-gdk"
Lecture-écriture
Couleur d'arrière-plan, sous la forme d'une
gtk.gdk.Color.
"foreground-gdk"
Lecture-écriture
Couleur d'avant-plan, sous la forme d'une
gtk.gdk.Color.
"font"
Lecture-écriture
Description de police, sous la forme d'une chaine de caractères.
"font-desc"
Lecture-écriture
Description de police, sous la forme d'une
pango.FontDescription.
"family"
Lecture-écriture
Nom de la famille de police (Sans, Helvetica, Times, Monospace, etc.).
"style"
Lecture-écriture
Style de police.
"variant"
Lecture-écriture
Variante de police.
"weight"
Lecture-écriture
Graisse de la police.
"stretch"
Lecture-écriture
Chasse de la police.
"size"
Lecture-écriture
Taille de la police.
"size-points"
Lecture-écriture
Taille de la police en points.
"scale"
Lecture-écriture
Facteur de taille de la police.
"editable"
Lecture-écriture
Si elle vaut TRUE, le texte peut être
édité par l'utilisateur.
"strikethrough"
Lecture-écriture
Si elle vaut TRUE, le texte est barré.
"underline"
Lecture-écriture
Style de soulignement du texte.
"rise"
Lecture-écriture
Position du texte par rapport à la ligne de base
(au-dessus si positif, au-dessous si négatif).
"language"
Lecture-écriture
La langue dans laquelle est rédigé le texte, sous la forme
d'un code ISO. Peut servir à Pango lors de l'affichage du texte. Si vous ne
comprenez pas ce paramètre, il est fort probable que vous n'en ayez pas besoin.
GTK+ 2.4 et supérieur.
"single-paragraph-mode"
Lecture-écriture
Si elle vaut TRUE, tout le texte sera maintenu
dans un seul paragraphe. GTK+ 2.4 et supérieur.
"background-set"
Lecture-écriture
Si elle vaut TRUE, applique la couleur d'arrière-plan.
"foreground-set"
Lecture-écriture
Si elle vaut TRUE, applique la couleur d'avant-plan.
"family-set"
Lecture-écriture
Si elle vaut TRUE, applique la famille de police.
"style-set"
Lecture-écriture
Si elle vaut TRUE, applique le style de police.
"variant-set"
Lecture-écriture
Si elle vaut TRUE, applique la variante de police.
"weight-set"
Lecture-écriture
Si elle vaut TRUE, applique la graisse de police.
"stretch-set"
Lecture-écriture
Si elle vaut TRUE, applique la chasse de police.
"size-set"
Lecture-écriture
Si elle vaut TRUE, applique la taille de police.
"scale-set"
Lecture-écriture
Si elle vaut TRUE, applique le facteur de taille
de police.
"editable-set"
Lecture-écriture
Si elle vaut TRUE, applique la possibilité ou non
d'éditer le texte.
"strikethrough-set"
Lecture-écriture
Si elle vaut TRUE, applique le trait barrant
le texte.
"underline-set"
Lecture-écriture
Si elle vaut TRUE, applique le soulignement
du texte.
"rise-set"
Lecture-écriture
Si elle vaut TRUE, applique le positionnement
du texte par rapport à la ligne de base.
"language-set"
Lecture-écriture
Si elle vaut TRUE, applique la langue utilisée
pour afficher le texte. GTK+ 2.4 et supérieur.
La quasi totalité des propriétés du CellRendererText
possède un équivalent booléen (avec le suffixe "-set") qui indique si la propriété
doit être appliquée. Cela permet de définir une propriété globalement et d'activer
ou non son application de manière sélective.
Le CellRendererToggle possède les propriétés
suivantes :
"activatable"
Lecture-écriture
Si elle vaut TRUE, le bouton à bascule peut
être activé.
"active"
Lecture-écriture
Si elle vaut TRUE, le bouton est actif.
"radio"
Lecture-écriture
Si elle vaut TRUE, le bouton à bascule sera
dessiné comme un bouton radio.
"inconsistent"
Lecture-écriture
Si elle vaut TRUE, le bouton sera dans un
état inconsistant. GTK+ 2.2 et supérieur.
Les propriétés peuvent être définies pour l'ensemble des lignes en
utilisant la méthode gobject.set_property(), comme
dans le programme
treeviewcolumn.py, par exemple.
14.4.4. Les attributs du CellRenderer
Les attributs associent une colonne de TreeModel à une propriété de
CellRenderer ; le CellRenderer
définit la propriété à partir de la valeur de colonne de la ligne avant d'afficher
la cellule. Cela permet de personnaliser l'affichage des cellules en utilisant
les données du modèle. On peut ajouter un attribut à l'ensemble courant de la
manière suivante :
... fixe, pour chaque ligne, le texte à partir de la première colonne,
la couleur d'arrière-plan à partir de la deuxième et l'espacement à gauche et
à droite de la cellule à partir de la quatrième. Le programme treeviewcolumn.py
donne des exemples d'utilisation de ces méthodes.
Les attributs d'un CellRenderer peuvent être
supprimés comme suit :
treeviewcolumn.clear_attributes(cell_renderer)
14.4.5. Fonction d'affichage des données cellulaires
Si définir des attributs ne suffit pas, il est possible de définir une
fonction à appeler à chaque ligne pour fixer les propriétés du
CellRenderer :
... où colonne est le
TreeViewColumn contenant le
cell_renderer, tree_model est
le modèle et iter est un
TreeIter pointant vers une ligne du
tree_model. donnees_utilisateur contient la
valeur des donnees transmises par la méthode
set_cell_data_func().
Dans fonction_rendu on peut définir toutes les propriétés
voulues du cell_renderer. La portion de code suivante
définit la propriété "text" pour afficher les objets PyGTK sous la forme d'une chaine
les identifiant.
Figure 14.3. Fonction d'affichage des données cellulaires
Cette fonction permet aussi de contrôler l'affichage des données
numériques en format texte (par exemple d'un nombre réel). Un
CellRendererText affiche et convertit
automatiquement un réel en chaine avec le format par défaut
"%f".
Les fonctions d'affichage de données cellulaires permettent même de créer
les données des colonnes à partir de données externes. Le programme listefichiers.py
utilise un ListStore avec une seule colonne contenant
une liste de fichiers. Le TreeView affiche des colonnes
qui comprennent un pixbuf, le nom du fichier, sa taille, son mode et la date
de dernière modification. Les données sont créées par la fonction suivante :
Figure 14.4. Exemple de liste de fichiers utilisant les fonctions d'affichage de données cellulaires
14.4.6. CellRendererText Markup
Un CellRendererText peut présenter un texte enrichi
avec des polices et des styles différents plutôt qu'une simple chaine de caractères
bruts grâce à l'utilisation du balisage Pango (en définissant la propriété "markup").
On trouvera davantage de renseignements sur le balisage Pango dans la section
Pango
Markup du
PyGTK Reference Manual.
L'extrait de code ci-dessous montre l'utilisation de la propriété
"markup" :
Lorsque l'on crée un balisage Pango à la volée, il faut faire attention
à remplacer les caractères spécifiques au langage balisé : "<", ">",
"&". La fonction cgi.escape() de la bibliothèque
Python peut réaliser ces conversions élémentaires.
14.4.7. Cellules de texte éditables
Les cellules CellRendererText peuvent
devenir éditables pour permettre à un utilisateur de changer le contenu de la
cellule sélectionnée en la cliquant ou en pressant une des touches Retour,
Entrée, Espace ou Maj+Espace.
On rend un CellRendererText éditable pour toutes
les lignes en fixant sa propriété "editable" à TRUE
de cette façon :
cellrenderertext.set_property('editable', True)
Pour rendre éditable une seule cellule, il faut ajouter un attribut au
TreeViewColumn et utiliser le
CellRendererText ainsi :
... qui fixe la propriété "editable" pour la valeur contenue dans
la troisième colonne du treemodel.
Les modifications de la cellule terminées, l'application doit gérer le signal
"edited" pour récupérer le nouveau texte et modifier la valeur du treemodel associé.
Sinon, la cellule reprend sa valeur précédente. Le gestionnaire
du signal "edited" a la signature suivante :
... où celltext est le CellRendererText,
chemin est le chemin d'accès (une chaine) à la ligne
contenant la cellule éditée, nouveau_texte est le texte modifié
et donnees_utilisateur les données contextuelles.
Le TreeModel étant indispensable pour définir le
nouveau_texte dans le stock de données, il faudra peut-être
transmettre le TreeModel comme
donnees_utilisateur dans la méthode
connect() :
S'il y a deux ou plusieurs cellules éditables dans une ligne, on peut
passer le numéro de la colonne dans donnees_utilisateur,
en même temps que le TreeModel :
Les boutons CellRendererToggle peuvent être rendus
activables en fixant leur propriété "activatable" à TRUE.
De la même manière que pour les cellules éditables
CellRendererText,
la propriété "activable" peut être fixée pour l'ensemble des cellules
CellRendererToggle en utilisant la méthode
set_property() ou pour des cellules individuelles
en ajoutant un attribut au TreeViewColumn contenant
le CellRendererToggle.
La déclaration individuelle des boutons à bascule peut être obtenue à partir
des valeurs d'une colonne du TreeModel en ajoutant un attribut,
comme ceci :
Une connexion au signal "toggled" est nécessaire si l'on veut savoir quand l'utilisateur
a cliqué sur le bouton et pouvoir modifier la valeur dans le treemodel. Par exemple :
... où chemin est le chemin d'accès (une chaine),
pointant sur la ligne contenant le bouton à bascule qui a été cliqué. On
doit passer le TreeModel et éventuellement l'index
de colonne dans le paramètre donnees_utilisateur pour fournir
les éléments nécessaires à l'établissement des valeurs du treemodel.
Par exemple, l'application peut modifier la valeur du treemodel
de la façon suivante :
Si l'on veut afficher les boutons à bascule comme des boutons
radio dont un seul serait sélectionné, l'application doit parcourir le treemodel
pour désactiver le bouton radio actif et ensuite déclarer le bouton à
activer. Par exemple, la fonction de rappel suivante :
def rappel_toggled(cellule, chemin, donnees_utilisateur):
modele, colonne = donnees_utilisateur
for ligne in modele:
ligne[colonne] = False
modele[chemin][colonne] = True
return
... utilise la solution de facilité qui consiste à mettre toutes les valeurs
du treemodel à FALSE avant de remettre à TRUE
la valeur pour la ligne indiquée par le chemin.
14.4.9. Programme d'exemple avec cellules éditables et activables
Le programme cellrenderer.py
illustre l'utilisation de CellRendererText éditables et de
CellRendererToggle activables dans un TreeStore.
1 #!/usr/bin/env python
2 # vim: ts=4:sw=4:tw=78:nowrap
3 """ Exemple avec Cellrenderer éditables et activables """
4 import pygtk
5 pygtk.require("2.0")
6 import gtk, gobject
7
8 taches = {
9 "Faire les courses": "Acheter une baguette",
10 "Programmer": "Mettre a jour le programme",
11 "Cuisiner": "Allumer le four",
12 "Regarder la TV": "Enregistrer \"Urgences\""
13 }
14
15 class GUI_Controleur:
16 """ La classe GUI est le controleur de l'application """
17 def __init__(self):
18 # Creation de la fenetre principale
19 self.fenetre = gtk.Window(type=gtk.WINDOW_TOPLEVEL)
20 self.fenetre.set_title("Exemple de CellRenderer")
21 self.fenetre.connect("destroy", self.evnmt_destroy)
22 # On recupere le modele et on le relie a la vue
23 self.modele = Ranger.recup_modele()
24 self.vue = Afficher.cree_vue( self.modele )
25 # Ajouter la vue a la fenetre principale
26 self.fenetre.add(self.vue)
27 self.fenetre.show_all()
28 return
29 def evnmt_destroy(self, *kw):
30 """ Fonction de rappel pour fermer l'application """
31 gtk.main_quit()
32 return
33 def lance(self):
34 """ La fonction est appelee pour lancer la boucle principale GTK """
35 gtk.main()
36 return
37
38 class InfoModele:
39 """ La classe du modele contient l'information que nous voulons afficher """
40 def __init__(self):
41 """ Creation et remplissage du gtk.TreeStore """
42 self.tree_store = gtk.TreeStore( gobject.TYPE_STRING,
43 gobject.TYPE_BOOLEAN )
44 # on place les donnees utilisateur globales dans une liste
45 # on cree une arborescence simple.
46 for item in taches.keys():
47 lignemere = self.tree_store.append( None, (item, None) )
48 self.tree_store.append( lignemere, (taches[item],None) )
49 return
50 def recup_modele(self):
51 """ Renvoie le modele """
52 if self.tree_store:
53 return self.tree_store
54 else:
55 return None
56
57 class AfficheModele:
58 """ Affiche le modele InfoModele dans un treeview """
59 def cree_vue( self, modele ):
60 """ Cree une vue pour le Tree Model """
61 self.vue = gtk.TreeView( modele )
62 # Cree le CellRendererText et permet aux cellules
63 # d'etre editees.
64 self.renderer = gtk.CellRendererText()
65 self.renderer.set_property( 'editable', True )
66 self.renderer.connect( 'edited', self.rappel_edited_col0, modele )
67
68 # Cree le CellRendererToggle et permet sa
69 # modification (toggled) par l'utilisateur.
70 self.renderer1 = gtk.CellRendererToggle()
71 self.renderer1.set_property('activatable', True)
72 self.renderer1.connect( 'toggled', self.rappel_toggled_col1, modele )
73
74 # On connecte la colonne 0 de l'affichage a la colonne 0 du modele
75 # Le cellrenderer va alors afficher tout ce qui est en colonne 0 de
76 # notre modele .
77 self.colonne0 = gtk.TreeViewColumn("Nom", self.renderer, text=0)
78
79 # L'etat actif des colonnes est relie a la seconde colonne
80 # du modele. Ainsi, quand le modele indique True, le bouton
81 # apparaitra comme actif.
82 self.colonne1 = gtk.TreeViewColumn("Fait", self.renderer1 )
83 self.colonne1.add_attribute( self.renderer1, "active", 1)
84 self.vue.append_column( self.colonne0 )
85 self.vue.append_column( self.colonne1 )
86 return self.vue
87 def rappel_edited_col0( self, cellrenderer, chemin, nouveau_texte, modele ):
88 """
89 Appele quand un texte est modifie. Il inscrit le nouveau texte
90 dans le modele pour qu'il puisse etre affiche correctement.
91 """
92 print "Change '%s' en '%s'" % (modele[chemin][0], nouveau_texte)
93 modele[chemin][0] = nouveau_texte
94 return
95 def rappel_toggled_col1( self, cellrenderer, chemin, modele ):
96 """
97 Fixe l'etat du bouton a bascule sur true ou false.
98 """
99 modele[chemin][1] = not modele[chemin][1]
100 print "Valeur de '%s' : %s" % (modele[chemin][0], modele[chemin][1],)
101 return
102
103 if __name__ == '__main__':
104 Ranger = InfoModele()
105 Afficher = AfficheModele()
106 monGUI = GUI_Controleur()
107 monGUI.lance()
Le programme propose des cellules éditables dans la première colonne
et des cellules activables dans la deuxième. Les lignes 64-66 créent un
CellRendererText éditable et connectent le signal
"edited" à la fonction de rappel rappel_edited_col0()
(lignes 87-94) qui modifie la valeur de colonne de la ligne adéquate dans
le TreeStore. De même, les lignes 70-72 créent un
CellRendererToggle activable et connectent le
signal "toggled" à la fonction de rappel rappel_toggled_col0()()
(lignes 95-101) qui modifie la valeur de la ligne adéquate. Lorsqu'une cellule
éditable ou activable est modifiée, un message s'affiche, indiquant de quelle
modification il s'agissait.