next up previous contents
suivant: Les barres d'état monter: Les widgets précédent: Le widget CList   Table des matières


Sous-sections

Le widget Arbre

Le but du widget Arbre est d'afficher des données hiérarchiquement organisées. Le widget Arbre lui-même est une conteneur vertical pour les widget de type TreeItem. Arbre n'est pas très différent d'une CList - les deux sont dérivés de Container, et les méthodes de Container fonctionnent aussi bien pour les widgets Arbre que pour les widgets CList. La différence est que les widgets Arbre peuvent être nichés dans d'autres widgets Arbre. Nous verrons brièvement comment faire cela.

Le widget Arbre possède sa propre fenêtre et possède par défaut un fond blanc comme les CList. Quoi qu'il en soit, Arbre ne dérive pas de CList donc nous ne pouvons utiliser l'un ou l'autre indifféremment.

Créer un Arbre

Un arbre est créé selon la méthode habituelle :

Comme les widgets CList, un widget Arbre continuera de grandir tant qu'on lui ajoutera des éléments, ou quand les subtrees ( sous-arbres ) prendront de l'ampleur. Pour cette raison, ils sont presque toujours placés dans une fenêtre défilable. Vous voudrez certainement utiliser set_usize() pour la fenêtre défilable afin de vous assurer qu'elle est assez grosse pour afficher les items de l'Arbre, car la taille par défaut d'une fenêtre défilable est plutôt petite.

Maintenant que nous avez un arbre vous voudrez certainement y ajouter quelques éléments. La section sur les TreeItems donne des détails ``crus'' sur les TreeItem. Pour l'instant, il suffit d'en créer un :

Vous pouvez l'ajouter à l'arbre en utilisant une des fonctions suivantes :

Notez que vous devez ajouter les éléments un par un - Il n'y a pas l'équivalent des fonctions sur les items d'un Clist.

Ajouter un sous-arbre

Un sous-arbre est créé comme un autre widget Arbre. Un sous-arbre est ajouté à un arbre sous un item arbre à l'aide de :

Vous n'avez pas besoin d'appeler la fonction show() pour un sous-arbre avant ou après l'avoir ajouté à un TreeItem. Quoiqu'il en soit, vous devez ajouter le TreeItem en question à un arbre parent avant d'appeler set_subtree(). C'est parce que, techniquement, le parent du sous-arbre n'est pas le TreeItem qui le possède mais l'arbre qui possède le TreeItem.

Quand vous ajoutez un sous-arbre à un TreeItem, un signe plus ou moins apparaît à son côté sur lequel l'utilisateur peut cliquer pour le ``développer'' ou le ``réduire ``, ce qui signifie montrer ou cacher le sous-arbre. Les TreeItems sont par défaut réduits. Notez que quand vous réduisez un sous-arbre, n'importe quel item sélectionné dans son sous-arbre reste sélectionné ce que l'utilisateur n'attend pas spécialement.

Manipuler une liste de sélection

Comme avec une CList, le type arbre possède un champs de sélection et il est possible de contrôler le comportement de l'arbre ( à peu près ) en déclarant le type de sélection avec :

Le sens des mots associés aux différents modes de sélection sont décrits dans la section sur les widgets Clist. Comme avec les widgets CList, les signaux select_child, unselect_child ( pas vraiment - voir la section sur les signaux ci-dessous )et selection_changed sont émis quand des items de la liste sont sélectionnés ou désélectionnés. Toutefois, pour tirer parti de ces signaux il faut savoir par quel widget arbre ils sont émis et où trouver la liste des items sélectionnés.

C'est une source de confusion potentielle. Le meilleur moyen d'expliquer ceci est de penser que tous les widgets Arbres sont créés égaux, et certains sont plus égaux que d'autres. Tous les widgets Arbres possèdent leurs propres fenêtres X, et peuvent par conséquent recevoir des évènements comme les clics de souris ( si leurs TreeItems ou leurs enfants peuvent les capter en premier ). Toutefois pour faire que des sélections du type 'single' ou 'browse' se comportent d'une manière saine, la liste des items sélectionnés est spécifique au widget Arbre le plus élevé dans la hiérarchie, connu comme ``l'arbre racine''.

Ainsi, accéder à une champs de sélection directement dans un widget arbre n'est pas une bonne idée à moins que vous ne sachiez s'il s'agit de l'arbre racine.

Enfin, les signaux select_child ( et en théorie, unselect_child ) sont émis par tous les arbres mais le signal selection_changed est uniquement émis par l'arbre racine. Par conséquent, si vous voulez manipuler le signal select_child pour un arbre et tous ses sous-arbres, vous devrez appeler signal_connect() pour tous les sous-arbres.

Composition d'un widget Arbre

Le champs d'une arbre ( à partir de sa structure C ) ressemble à :

En plus, is_root_tree() retourne une valeur booléenne qui indique si un arbre est un arbre racine dans une hiérarchie arbre alors que root_tree() retourne l'arbre racine.

Plutôt que d'accéder directement au champs enfant d'un widget arbre, il est probablement meilleur d'y accéder en utilisant la fonction children(), héritée du widget Container.

Le champs tree_owner est défini uniquement dans les sous-arbres, où il pointe vers le widget TreeItem qui possède l'arbre en question. Le champs level indique à quel point est ``niché'' un arbre particulier ; les arbres racines ont le niveau 0 et chaque niveau successif de sous-arbres a une niveau supérieur à celui du niveau parent augmenté de 1. En fait, ce champs est déclaré un fois que le widget Arbre est représenté ( tracé à l'écran ).

Les signaux

Le signal selection_changed sera émis quelque soit le champs selection de l'arbre modifié. Cela arrive quand un enfant de l'arbre est sélectionné ou désélectionné.

Le signal select_child est émis quand un enfant de l'arbre est sur le point d'être sélectionné. Cela arrive sur les appels select_item(), select_child(), sur tous les boutons pressés et les appels item_toggle() et toggle(). Cela peut parfois être déclenché en d'autres occasions, quand des enfants sont ajoutés ou enlevés de l'arbre.

Le signal unselect_child est émis quand un enfant de l'arbre est sur le point d'être désélectionné. Comme avec GTK 1.0.4, cela semble n'arriver que lors des appels unselect_item() ou unselect_child() et peut être en d'autres occasions, mais pas quand un bouton pressé désélectionne un enfant ( le signal select_child est émis à la place ), ni lors de l'émission du signal toggle par gtk_item_toggle().

Les fonctions

Insère un item arbre dans un Arbre à la position spécifiée

Enlève une liste d'éléments de l'Arbre. Notez qu'enlever un élément d'un arbre le déréférence et ( habituellement ) le détruit lui et son sous-arbre, s'il en a, et tous les sous-arbres dans ces sous-arbres. Si vous voulez enlever uniquement un élément, vous pouvez utiliser remove().

Enlève les éléments compris entre la position $start et $end. Le même avertissement ici à propos du déférencement qui s'applique car clear_items() construit simplement la liste et la passe ensuite à remove_items().

Émet le signal select_item pour un enfant à la position $item, le sélectionnant ainsi ( sauf si vous le désélectionnez avec un gestionnaire de signal ).

Émet le signal unselect_item pour un enfant à la position $item, le désélectionnant ainsi.

Émet le signal select_item pour un enfant $tree_item, le sélectionnant ainsi.

Émet le signal unselect_item pour un enfant $tree_item, le désélectionnant ainsi.

Retourne la position dans un un arbre de $child à moins que $child ne soit pas dans l'arbre, dans ce cas retourne -1.

Déclare le mode de sélection, qui peut être single ( le défaut ), browse, multiple ou extended. Cela est seulement défini pour les arbres racines, ce qui tombe sous le sens puisque les arbres racines ``possèdent'' la sélection. Faire cette déclaration sur un sous-arbre n'a aucun effet, la valeur est simplement ignorée.

Déclare le mode ``view'' qui peut être soit line ( le défaut) soit item. Le mode ``view'' se propage d'un arbre à ses sous-arbres quand ils sont représentés, et ne concerne pas exclusivement un sous-arbre. ( le déclarer sur un sous-arbre après qu'il ait été représenté pourrait avoir des effet quelque peu imprévisibles ).

Le terme mode ``view'' est plutôt ambigu - à la base, cela contrôle la manière dont la coloration est représentée quand l'un des enfant de l'arbre est sélectionné. Si c'est line, l'arbre entier est coloré alors que si c'est item, seul le widget enfant ( habituellement le label ) est coloré.

Contrôle si les lignes qui relient les éléments de l'arbre sont dessinées. $show_lines est une valeur vraie ou fausse.

Retourne l'arbre racine d'un objet arbre.

Retourne la liste de sélection d'un arbre racine d'un objet ``GtkTree''.

Le widget TreeItem

Le widget TreeItem, comme le CListItem, est dérivé de Item, qui à son tour est dérivé de Bin. Par conséquent, l'item lui-même est un conteneur générique contenant exactement un seul widget enfant qui peut être de n'importe quel type. Le widget TreeItem possède un nombre supplémentaire de champs mais le seul qui nous intéresse vraiment est le champs sous-arbre.

Les champs disponibles pour la structure TreeItem ressemblent à :

Le champs pixmaps_box est une Boîte d'évènements qui attrapent les clics sur le signe plus/moins qui contrôle le développement ou la réduction. Le champs pixmaps pointe vers une structure de données internes. Puisque vous pouvez toujours obtenir le sous-arbre d'un TreeItem avec la fonction subtree(), il est vivement conseillé de ne pas toucher à l'intérieur d'un TreeItem sauf si vous savez exactement ce que vous faîtes.

Un TreeItem possède habituellement un label, donc la fonction new_with_label Gtk::TreeItem() est fournie. Le même effet peut être obtenu en utilisant le code suivant :

Comme personne ne nous oblige à ajouter un label à un TreeItem, nous pouvons également ajouter une HBox ou une flèche, ou même un Notebook ( bien que dans ce cas, votre application risque d'être plutôt impopulaire ).

Si vous enlevez tous les éléments d'un sous-arbre, celui-ci sera détruit et ne sera plus rattaché à aucun parent, à moins que vous ne le référenciez plus tôt, et le TreeItem auquel il appartient sera réduit. Donc, si vous voulez qu'il reste en place, faîtes comme ceci :

Enfin, le drag and drop fonctionne avec les TreeItems. Vous devez juste vous assurer que le TreeItem dans lequel vous prenez un élément ou vous en placer un, a non seulement été ajouté à l'arbre mais que chaque widget parent successif possède lui-même un parent, tous jusqu'à une fenêtre toplevel ou dialogue, quand vous utilisez dnd_drag_set() ou dnd_drop_set(). Autrement de drôles de choses peuvent se produire.

TreeItem héritent des signaux select, unselect et toggle des Items. En plus, il possède deux autres signaux qui lui sont propres :expand et expand().

Le signal expand est émis quand le sous-arbre d'un arbre est sur le point d'être développé, c'est-à-dire quand l'utilisateur clique sur le signe plus placé à côté de l'élément, ou quand le programme appelle la fonction :expand().

Le signal collapse est émis quand le sous-arbre d'un arbre est sur le point d'être réduit, c'est-à-dire quand l'utilisateur clique sur le signe moins placé à côté de l'élément, ou quand le programme appelle la fonction :collapse().

Cela enlève tous les enfants de sous-arbres de tree_item ( donc les déréférence, les détruit, tous les sous-arbres des enfants et ainsi de suite...), puis le sous-arbre lui-même et cache le signe plus/moins.

Exemple

C'est un exemple un peu plus compliqué que les autres mais je pense que le moment est approprié. Bien qu'il illustre les widgets arbres, cet exemple utilise quelque peu les widget CList. A partir de là, nous pourrions facilement ajouter un bouton ou un menu et ajouter des fonctionnalités comme effacer, copier ou bouger un fichier ce qui nous ferait un file manager ``light''.

Tree Example


next up previous contents
suivant: Les barres d'état monter: Les widgets précédent: Le widget CList   Table des matières
LE BORGNE Patrice 2001-01-11