Vous êtes à peu près ici : Accueil  »   tutoriel PyGTK  »   PyGTK : sommaire

Chapitre 14. Le widget TreeView

Table des matières

14.1. Présentation
14.2. L'interface TreeModel et le stockage des données
14.2.1. Introduction
14.2.2. Créer des objets TreeStore et ListStore
14.2.3. Les références aux lignes du modèle
14.2.4. Ajouter des lignes
14.2.5. Supprimer des lignes
14.2.6. Manipuler les données des lignes
14.2.7. Support du protocole Python
14.2.8. Les signaux du TreeModel
14.2.9. Ordonner les lignes d'un TreeModel
14.3. Les TreeView
14.3.1. Créer un TreeView
14.3.2. Récupérer et spécifier le modèle du TreeView
14.3.3. Les propriétés du TreeView
14.4. Les CellRenderer
14.4.1. Vue d'ensemble
14.4.2. Les différents types de CellRenderer
14.4.3. Les propriétés des CellRenderer
14.4.4. Les attributs du CellRenderer
14.4.5. Fonction d'affichage des données cellulaires
14.4.6. CellRendererText Markup
14.4.7. Cellules de texte éditables
14.4.8. Cellules à bascule activables
14.4.9. Programme d'exemple avec cellules éditables et activables
14.5. TreeViewColumn
14.5.1. Créer des TreeViewColumn
14.5.2. Gérer les CellRenderer
14.6. Manipuler les TreeView
14.6.1. Gérer les colonnes
14.6.2. Afficher ou masquer les enfants d'une ligne
14.7. Les signaux des TreeView
14.8. Gestion des Treeselection
14.8.1. Obtenir un TreeSelection
14.8.2. Modes du TreeSelection
14.8.3. Retrouver la sélection
14.8.4. Utiliser une fonction TreeSelection
14.8.5. Sélectionner et déselectionner les lignes
14.9. Glisser-déposer dans un TreeView
14.9.1. Reclasser avec un glisser-déposer
14.9.2. Glisser-déposer externe
14.9.3. Exemple de glisser-déposer dans un TreeView
14.10. TreeModelSort et TreeModelFilter
14.10.1. Le TreeModelSort
14.10.2. Le TreeModelFilter
14.11. Le TreeModel générique
14.11.1. Aperçu du GenericTreeModel
14.11.2. Interface du GenericTreeModel
14.11.3. Ajouter et supprimer des lignes
14.11.4. Gestion de la mémoire
14.11.5. Autres interfaces
14.11.6. Utilisation du GenericTreeModel
14.12. The Generic CellRenderer

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.

14.1. Présentation

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 :

  • le 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.
  • le 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 :

  • le TreeModelSort est un modèle dans lequel les données du TreeModel inférieur sont maintenues dans un ordre donné.
  • the 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 :

  • Le CellRendererPixbuf, qui prend en charge l'affichage d'une image pixbuf dans les cellules d'un TreeViewColumn.
  • Le 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.
  • Le 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é) :

  • création d'un objet TreeModel, généralement un ListStore ou un TreeStore, avec une ou plusieurs colonnes d'un type spécifique de données.
  • placement éventuel d'une ou plusieurs lignes de données dans le TreeModel.
  • création d'un widget TreeView et association de ce dernier avec le TreeModel.
  • création d'un ou plusieurs TreeViewColumn et insertion de ces derniers dans le TreeView. Chacun représentera une colonne affichée.
  • création, pour chaque TreeViewColumn, d'un ou plusieurs CellRenderer qui y sont ensuite placés.
  • définition des attributs de chaque 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.
  • insertion et affichage du TreeView dans une fenêtre (gtk.Window) ou une fenêtre à défilement (gtk.ScrolledWindow).
  • programmation des manipulations de données à effectuer en réponse aux actions de l'utilisateur. Le 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.

Figure 14.1. Programme d'exemple de TreeView simple

Programme d'exemple de TreeView simple

Examinons à présent l'interface TreeModel et les modèles qui l'implémentent.