Table des matières
Le widget TreeView affiche des listes et des 
arborescences sur plusieurs colonnes. Il remplace les anciens widgets 
List, CList, 
Tree and CTree par un ensemble 
beaucoup plus puissant et flexible d'objets utilisant le principe 
Modèle-Vue-Contrôleur (MVC). Il propose :
La puissance de ce nouvel ensemble d'objets et d'interfaces a pour contrepartie une complexité indéniablement plus importante, pouvant même paraître insurmontable au début. Dans ce chapitre, les objets et les interfaces du TreeView seront présentés de manière à pouvoir en faire un usage courant. Nous vous laisserons le soin d'explorer par vous-même leurs aspects plus ésotériques.
Nous commencerons par un un bref aperçu de ces objets et interfaces, avant de nous plonger dans l'interface TreeModel et dans les classes prédéfinies ListStore et TreeStore.
Le widget TreeView est l'objet de l'interface utilisateur qui se charge d'afficher les données stockées dans un objet implémentant l'interface TreeModel. Deux classes TreeModel de base sont définies dans PyGTK 2.0 :
TreeStore, qui permet un stockage hiérarchique des données, organisé en lignes d'arborescence comportant des données dans des colonnes. Chaque ligne d'arborescence peut avoir zéro ou plusieurs lignes filles, et toutes les lignes doivent avoir le même nombre de colonnes.
ListStore, qui permet un stockage tabulaire des données, organisé en lignes et en colonnes de la même manière qu'un tableau dans une base de données relationnelle. Le ListStore est en réalité une version simplifiée du TreeStore dont les lignes n'ont pas de lignes filles. Il fut créé afin d'offrir une interface plus simple (et certainement plus efficace) de ce modèle commun de données.
Les deux autres TreeModel s'ajoutent par dessus (ou s'interposent entre) les modèles de base :
TreeModelSort est un modèle dans lequel les données du TreeModel inférieur sont maintenues dans un ordre donné.TreeModelFilter est un modèle contenant un sous-ensemble des données du modèle inférieur. Notez que ce modèle n'est disponible que dans PyGTK 2.4 et supérieurs.
Un TreeView affiche toutes les lignes d'un TreeModel mais pas forcément toutes les colonnes. Ces dernières peuvent en outre ne pas être présentées dans le même ordre que dans le TreeModel.
Le TreeView utilise des TreeViewColumn pour organiser l'affichage des données des colonnes. Chaque TreeViewColumn affiche une colonne (avec ou sans en-tête) pouvant contenir les données de plusieurs colonnes de TreeModel. Dans chaque TreeViewColumn sont placés (comme dans des conteneurs HBox) des CellRenderer, qui prennent en charge l'affichage des données correspondantes en provenance d'un emplacement ligne-colonne dans un TreeModel. Trois classes CellRenderer sont prédéfinies :
CellRendererPixbuf, qui prend en charge l'affichage d'une image pixbuf dans les cellules d'un TreeViewColumn.CellRendererText, qui prend en charge l'affichage d'une chaine de texte dans les cellules d'un TreeViewColumn. Si les données des colonnes ne sont pas des chaines de texte, il effectue la conversion. Par exemple, pour afficher une colonne de modèle contenant une donnée à virgule flottante (float), le CellRendererText la convertira en chaine avant de l'afficher.
CellRendererToggle affiche une valeur booléenne dans les cellules d'un TreeViewColumn sous la forme d'un bouton à bascule.
Un TreeViewColumn peut contenir plusieurs CellRenderer pour, par exemple, afficher de l'image et du texte dans une même colonne.
Enfin, les objets TreeIter, TreeRowReference et TreeSelection sont respectivement un pointeur temporaire vers une ligne d'un TreeModel, un pointeur permanent vers une ligne d'un TreeModel, et un objet gérant les sélections dans un TreeView.
Pour afficher un TreeView, on effectuera les opérations suivantes (sans nécessairement respecter l'ordre proposé) :
ListStore ou un TreeStore, avec une ou plusieurs colonnes d'un type spécifique de données.
TreeView et association de ce dernier 
avec le TreeModel.TreeViewColumn et insertion de ces derniers dans le TreeView. Chacun représentera une colonne affichée.
TreeViewColumn, d'un ou plusieurs CellRenderer qui y sont ensuite placés.
CellRenderer de manière à indiquer dans quelle colonne du TreeModel l'on doit récupérer les données de l'attribut. Par exemple, le texte à afficher. Cela permet au CellRenderer d'afficher différemment chaque colonne d'une ligne.
TreeView dans une fenêtre (gtk.Window) ou une fenêtre à défilement (gtk.ScrolledWindow).
TreeView doit suivre automatiquement les modifications.
Le programme d'exemple treeviewbasique.py illustre la création et l'affichage d'un TreeView simple.
    1   #!/usr/bin/env python
    2
    3   # exemple treeviewbasique.py
    4
    5   import pygtk
    6   pygtk.require('2.0')
    7   import gtk
    8
    9   class ExempleTreeViewBasique:
   10
   11       # fermeture de la fenetre et sortie du programme
   12       def evnmt_delete(self, widget, evnmt, donnees=None):
   13           gtk.main_quit()
   14           return False
   15
   16       def __init__(self):
   17           # Creation d'une nouvelle fenetre
   18           self.fenetre = gtk.Window(gtk.WINDOW_TOPLEVEL)
   19
   20           self.fenetre.set_title("Exemple TreeView simple")
   21
   22           self.fenetre.set_size_request(200, 200)
   23
   24           self.fenetre.connect("delete_event", self.evnmt_delete)
   25
   26           # Creation d'un TreeStore avec une colonne de type chaine, pour servir de modele
   27           self.treestore = gtk.TreeStore(str)
   28
   29           # Ajoutons des donnees : 4 lignes ayant 3 lignes filles chacune
   30           for mere in range(4):
   31               m_iter = self.treestore.append(None, ['ligne mere %i' % mere])
   32               for fille in range(3):
   33                   self.treestore.append(m_iter, ['ligne fille %i de la ligne %i'
   34                                                 % (fille, mere)])
   35
   36           # creation du TreeView en utilisant notre TreeStore
   37           self.treeview = gtk.TreeView(self.treestore)
   38
   39           # creation du TreeViewColumn pour afficher les donnees
   40           self.tvcolumn = gtk.TreeViewColumn('Column 0')
   41
   42           # on place tvcolumn dans notre TreeView
   43           self.treeview.append_column(self.tvcolumn)
   44
   45           # creation d'un CellRendererText pour afficher les donnees
   46           self.cell = gtk.CellRendererText()
   47
   48           # on place cell dans le TreeViewColumn et on lui permet de s'etirer
   49           self.tvcolumn.pack_start(self.cell, True)
   50
   51           # reglage de l'attribut "text" de cell sur la colonne 0 - recupere le
   52           # texte dans cette colonne du TreeStore
   53           self.tvcolumn.add_attribute(self.cell, 'text', 0)
   54
   55           # on autorise la recherche
   56           self.treeview.set_search_column(0)
   57
   58           # on autorise la classement de la colonne
   59           self.tvcolumn.set_sort_column_id(0)
   60
   61           # on autorise le classement des lignes par glisser-deposer
   62           self.treeview.set_reorderable(True)
   63
   64           self.fenetre.add(self.treeview)
   65
   66           self.fenetre.show_all()
   67
   68   def main():
   69       gtk.main()
   70
   71   if __name__ == "__main__":
   72       exempletv = ExempleTreeViewBasique()
   73       main()
Dans de vrais programmes, les données seraient probablement fournies au TreeStore après l'affichage du TreeView, par une action de l'utilisateur. Nous étudierons en détail les interfaces du TreeView dans les prochaines sections. La Figure 14.1, « Programme d'exemple de TreeView simple »  montre la fenêtre créée par le programme treeviewbasique.py après que quelques lignes ont été développées.
Examinons à présent l'interface TreeModel et les modèles qui l'implémentent.