Date de publication : 20 Février 2007
Nous allons étudier dans ce chapitre comment afficher des données
sous forme de liste ou d'arbre. Le widget GtkTreeView
utilise plusieurs
widgets pour permettre l'affichage de données.
L'utilisation de ce widget se décompose en deux parties distinctes :
La création du modèle se fait soit par l'utilisation de GtkListStore
pour créer une liste, soit par GtkTreeStore
pour la création
d'un arbre. C'est deux objets stockent dans un premier temps la structure des
données, c'est à dire le nombre de colonnes, le type d'affichage
(texte, image, case à cocher) et stockent dans un second temps les données
qui seront affichées par la suite.
Une fois le modèle créer, nous pouvons passer à la partie
affichage des données. Le widget principal est bien sûr GtkTreeView
qui utilise dans un premier temps l'objet GtkTreeViewColumn
qui
servira à définir chaque colonne du widget. Et enfin pour chaque
colonne il faut définir le type d'affichage à l'aide des objets
GtkCellRendererText
(pour afficher du texte), GtkCellRendererPixbuf
(pour afficher une image) et GtkCellRenderToggle
(pour afficher
une case à cocher).
Regardons maintenant comment coder cela.
Pour créer un modèle de type liste, nous allons utiliser cette fonction :
GtkListStore* gtk_list_store_new(gint n_columns, ...);
Le premier paramètre de cette fonction défini le nombre de colonnes
du modèle et donc du GtkTreeView
. A la suite de ce paramètre,
il faut définir le type de donnée qui sera stockée dans
chaque colonne. Les types les plus communs sont :
Une fois que les différentes colonnes sont définies, nous allons voir comment ajouter des éléments à la liste.
La première étape de l'insertion consiste à créer
une nouvelle entrée (ligne) à la liste. Pour cela, nous allons
utiliser l'objet GtkTreeIter
. Cet objet permet de savoir à
quel endroit nous nous positionnons dans la liste. La création d'une
nouvelle ligne va donner une nouvelle position dont nous avons besoin pour entrer
les données.
Voici la liste des fonctions qui permettent de créer une nouvelle entrée :
void gtk_list_store_append(GtkListStore *list_store, GtkTreeIter
*iter);
void gtk_list_store_prepend(GtkListStore *list_store, GtkTreeIter *iter);
void gtk_list_store_insert(GtkListStore *list_store, GtkTreeIter *iter, gint
position);
void gtk_list_store_insert_before(GtkListStore *list_store, GtkTreeIter *iter,
GtkTreeIter *sibling);
void gtk_list_store_insert_after(GtkListStore *list_store, GtkTreeIter *iter,
GtkTreeIter *sibling);
Pour chacune de ces fonctions, le premier paramètre list_store
est la liste qui a été crée précédemment
et le deuxième paramètre iter
, est la position de
la ligne nouvellement crée.
Les deux premières fonctions sont les plus couramment utilisées
lors de la création de la liste. La première fonction crée
une nouvelle ligne à la fin de la liste tandis que la deuxième
fonction l'ajoute au début de la liste.
Les trois fonctions suivantes permettent d'introduire une nouvelle ligne à
une position bien précise. La troisième fonction l'ajoute par
rapport à une valeur numérique (paramètre position
),
la quatrième fonction l'ajoute avant une ligne bien définie par
son itération sibling
et la cinquième fonction l'ajoute
après une ligne définie de la même manière.
Il faut maintenant définir le contenu de la nouvelle ligne, en utilisant cette unique fonction :
void gtk_list_store_set(GtkListStore *list_store, GtkTreeIter *iter, ...);
Les paramètres list_store
et iter
sont bien
sûr la liste et la ligne pour laquelle nous voulons spécifier les
données. A la suite de ces deux paramètres il suffit d'ajouter
les différentes données avec dans l'ordre la colonne de la donnée
suivie de sa valeur. Et pour terminer, il faut dire à cette fonction
que la liste des données est terminée simplement en ajoutant -1
en dernier paramètre.
La liste est maintenant prête à l'affichage.
Nous allons maintenant voir les légères différences qu'il
y a entre la création d'une liste et la création d'un arbre à
l'aide de l'objet GtkTreeStore
. La principale différence
est que chaque ligne peut avoir une ligne parente et une ou plusieurs lignes
enfants. Nous n'avons donc plus affaire à une simple succession de lignes,
mais à une organisation imbriquée de succession de lignes.
La fonction de création est très ressemblante à celle
de l'objet GtkListStore
:
GtkTreeStore* gtk_tree_store_new(gint n_columns, ...);
Bien entendu, le paramètre n_columns
est le nombre de colonne
de chaque ligne de l'arbre, suivi des différents types des données.
Cette fois aussi les fonctions sont presque identiques à celles fournies pour les listes :
void gtk_tree_store_append(GtkTreeStore *tree_store, GtkTreeIter
*iter, GtkTreeIter *parent);
void gtk_tree_store_prepend(GtkTreeStore *tree_store, GtkTreeIter *iter, GtkTreeIter
*parent);
void gtk_tree_store_insert(GtkTreeStore *tree_store, GtkTreeIter *iter, GtkTreeIter
*parent, gint position);
void gtk_tree_store_insert_before(GtkTreeStore *tree_store, GtkTreeIter *iter,
GtkTreeIter *parent, GtkTreeIter *sibling);
void gtk_tree_store_insert_after(GtkTreeStore *tree_store, GtkTreeIter *iter,
GtkTreeIter *parent, GtkTreeIter *sibling);
La grande nouveauté, avec toutes ces fonctions, est la présence
d'un paramètre supplémentaire, parent
, de type GtkTreeIter,
qui n'est autre que la ligne dont notre nouvel élément sera l'enfant.
Si notre nouvelle ligne n'a pas de parent, ce paramètre sera à
NULL, sinon il faudra mettre l'itération correspondant à la ligne
parente.
Et pour finir, il faut définir les valeurs de chaque colonne grâce à cette fonction :
void gtk_tree_store_set(GtkTreeStore *tree_store, GtkTreeIter *iter, ...);
De la même façon que pour les éléments de type GtkListStore
,
la liste de valeurs doit se terminer par -1.
Maintenant que le modèle du widget GtkTreeView
a été
créé, il faut gérer l'affichage de celui-ci. Cela va se
dérouler en deux étapes distinctes :
Le déroulement des ces différentes étapes est identique
que cela soit avec un modèle de type GtkListStore
qu'avec
un modèle de type GtkTreeStore
.
Il existe deux fonctions de création du widget GtkTreeView :
GtkWidget* gtk_tree_view_new(void);
GtkWidget* gtk_tree_view_new_with_model(GtkTreeModel *model);
La première fonction crée une vue vide, alors que la deuxième
fonction créera la vue à partir du modèle spécifié.
Que l'on utilise un GtkListStore
ou un GtkTreeStore
,
il faudra utiliser la macro GTK_TREE_MODEL
pour spécifier
le paramètre model
.
Si la première fonction est utilisée pour la création
de la vue, il faudra tout de même donner à la vue un modèle
bien précis, pour que lors de l'affichage GTK+
sache quelles
données il doit afficher, avec cette fonction :
void gtk_tree_view_set_model(GtkTreeView *tree_view, GtkTreeModel *model);
Lors de cette étape, nous allons introduire deux nouveaux objets. Tout
d'abord l'objet GtkCellRenderer
et ses dérivés, puis
l'objet GtkTreeViewColumn
. Nous allons donc maintenant voir comment
ajouter les différentes colonnes à notre vue et aussi de quelle
manière doit être fait le rendu.
La manière dont les cases d'une colonne sont rendues se défini
à l'aide des objets dérivés de GtkCellRenderer
:
GtkCellRendererText
pour afficher du texte ;GtkCellRendererToggle
pour afficher une case à cocher
ou un bouton radio ;GtkCellRendererPixbuf
pour afficher une image.Pour créer un de ces objets, nous avons les fonctions suivantes :
GtkCellRenderer* gtk_cell_renderer_text_new(void);
GtkCellRenderer* gtk_cell_renderer_toggle_new(void);
GtkCellRenderer* gtk_cell_renderer_pixbuf_new(void);
Une fois le GtkCellRenderer
créé, nous pouvons modifier
différents paramètres à l'aide de cette fonction :
void g_object_set(gpointer object, const gchar *first_property_name, ...);
Le premier paramètre, object
, est l'objet que l'on veut
modifier. Il faut utiliser pour ce paramètre la macro G_OBJECT()
.
Puis, les paramètres suivants vont par couple paramètre/valeur
pour modifier par exemple la couleur de fond de la case ou autre. Une fois tous
les paramètres à modifier entrés, il faut ajouter NULL
pour dire que la liste des modifications à apporter est terminée.
La liste des paramètres que nous pouvons modifier pour les objets de
types GtkCellRenderer
est disponible dans la section "En
savoir plus"
de ce chapitre.
Maintenant que nous savons comment les cases d'une colonne doivent être rendues, nous allons voir comment créer une colonne et comment l'ajouter à la vue. Pour créer une colonne, nous avons cette fonction :
GtkTreeViewColumn* gtk_tree_view_column_new_with_attributes(const gchar *title, GtkCellRenderer *cell, ...);
Le premier paramètre, title
, est le texte qui sera affiché
en haut de la colonne dans une ligne bien spécifique. Le second paramètre,
cell
, est simplement l'objet GtkCellRenderer
que nous
venons juste de créer, définissant le rendu de chaque case de
la colonne.
Ensuite, il faut à nouveau définir le type de la colonne ainsi
que le numéro de la colonne dans le modèle. Les types de colonnes
sont "text"
pour du texte, "active"
pour une case à cocher, "pixbuf"
pour une image.
Et pour terminer, comme souvent dans ce type de fonction, il faut ajouter NULL
à la suite de tous les paramètres pour dire que la liste est terminée.
Il ne nous reste plus qu'à ajouter la colonne à la vue avec l'une de ces fonctions :
gint gtk_tree_view_append_column(GtkTreeView *tree_view, GtkTreeViewColumn
*column);
gint gtk_tree_view_insert_column(GtkTreeView *tree_view, GtkTreeViewColumn *column,
gint position);
La première fonction ajoute la colonne à la suite des autres,
tandis que la seconde l'ajoute à la position position
ou
à la suite des autres si la valeur de position
est invalide.
La macro GTK_TREE_VIEW()
est à utiliser pour le premier
paramètre.
Nous allons créer deux exemples pour montrer l'utilisation du widget GtkTreeView. Dans le premier exemple, nous allons créer une liste avec simplement une colonne avec du texte et une colonne comportant une case à cocher. Le deuxième exemple, utilisera quant à lui un arbre avec une première colonne affichant une image, et du texte dans la deuxième colonne.
#include <stdlib.h> enum { int main(int
argc, char **argv) gtk_init(&argc, &argv); /* Creation de la fenetre
principale */ /* Creation du modele */ sTexte = g_malloc(12); /* Insertion des elements
*/ sprintf(sTexte, "Ligne %d\0", i); /*
Creation de la nouvelle ligne */ /*
Mise a jour des donnees */ g_free(sTexte); /* Creation de la vue */ /* Creation de la premiere
colonne */ /* Ajout de la colonne
à la vue */ /* Creation de la deuxieme
colonne */ /* Ajout de la colonne
à la vue */ /* Ajout de la vue a la
fenetre */ gtk_widget_show_all(pWindow); gtk_main(); return EXIT_SUCCESS;
|
Résultat : |
#include <stdlib.h> #include <stdio.h> #include <gtk/gtk.h> enum { /* Utilisateurs Visual C++ : il faut ajouter gdk_pixbuf-2.0.lib dans les options du linker */ int main(int
argc, char **argv) gtk_init(&argc, &argv); /* Creation de la fenetre
principale */ /* Creation du modele */ sTexte = g_malloc(16); /* Chargement des images
*/ /* Insertion des elements
*/ sprintf(sTexte, "Ordinateur %d", i); /*
Creation de la nouvelle ligne */ /*
Mise a jour des donnees */ for(j
= 0 ; j < 2 ; ++j) /*
Creation de la nouvelle ligne enfant */ /*
Mise a jour des donnees */ g_free(sTexte); g_object_unref(pPixBufA); /* Creation de la vue */ /* Creation de la premiere
colonne */ /* Ajout de la colonne
à la vue */ /* Creation de la deuxieme
colonne */ /* Ajout de la colonne
à la vue */ /* Ajout de la vue a la
fenetre */ gtk_widget_show_all(pWindow); gtk_main(); return EXIT_SUCCESS;
|
Résultat : |
GtkTreeView.
Propriété | Type | Accès | Description |
enable-search | gboolean | Lecture/Ecriture | |
expander-column | GtkTreeViewColumn | Lecture/Ecriture | |
hadjustment | GtkAdjustment | Lecture/Ecriture | |
headers-clickable | gboolean | Ecriture | |
headers-visible | gboolean | Lecture/Ecriture | |
model | GtkTreeMode | Lecture/Ecriture | |
reorderable | gboolean | Lecture/Ecriture | |
rules-hint | gboolean | Lecture/Ecriture | |
search-column | gint | Lecture/Ecriture | |
vadjustment | GtkAdjustment | Lecture/Ecriture | |
allow-rules | gboolean | Lecture | |
even-row-color | GdkColor | Lecture | |
expander-size | gint | Lecture | |
horizontal-separator | gint | Lecture | |
indent-expanders | gboolean | Lecture | |
odd-row-color | GdkColor | Lecture | |
vertical-separator | gint | Lecture |
GtkTreeViewColumn.
Propriété | Type | Accès | Description |
alignment | gfloat | Lecture/Ecriture | |
clickable | gboolean | Lecture/Ecriture | |
fixed-width | gint | Lecture/Ecriture | |
max-width | gint | Lecture/Ecriture | |
min-width | gint | Lecture/Ecriture | |
reorderable | gboolean | Lecture/Ecriture | |
resizable | gboolean | Lecture/Ecriture | |
sizing | GtkTreeViewColumnSizing | Lecture/Ecriture | |
sort-indicator | gboolean | Lecture/Ecriture | |
sort-order | GtkSortType | Lecture/Ecriture | |
title | gchararray | Lecture/Ecriture | |
visible | gboolean | Lecture/Ecriture | |
widget | GtkWidget | Lecture/Ecriture | |
width | gint | Lecture |
GtkCellRenderer
Propriété | Type | Accès | Description |
cell-background | gchararray | Ecriture | |
cell-background-gdk | GdkColor | Lecture/Ecriture | |
cell-background-set | gboolean | Lecture/Ecriture | |
height | gint | Lecture/Ecriture | |
is-expanded | gboolean | Lecture/Ecriture | |
is-expander | gboolean | Lecture/Ecriture | |
mode | GtkCellRendererMode | Lecture/Ecriture | |
visible | gboolean | Lecture/Ecriture | |
width | gint | Lecture/Ecriture | |
xalign | gfloat | Lecture/Ecriture | |
xpad | guint | Lecture/Ecriture | |
yalign | gfloat | Lecture/Ecriture | |
ypad | guint | Lecture/Ecriture |
GtkCellRenderText
Propriété | Type | Accès | Description |
attributes | PangoAttrList | Lecture/Ecriture | |
background | gchararray | Ecriture | |
background-gdk | GdkColor | Lecture/Ecriture | |
background-set | gboolean | Lecture/Ecriture | |
editable | gboolean | Lecture/Ecriture | |
editable-set | gboolean | Lecture/Ecriture | |
family | gchararray | Lecture/Ecriture | |
family-set | gboolean | Lecture/Ecriture | |
font | gchararray | Lecture/Ecriture | |
font-desc | PangoFontDescription | Lecture/Ecriture | |
foreground | gchararray | Ecriture | |
foreground-gdk | GdkColor | Lecture/Ecriture | |
foreground-set | gboolean | Lecture/Ecriture | |
markup | gchararray | Ecriture | |
rise | gint | Lecture/Ecriture | |
rise-set | gboolean | Lecture/Ecriture | |
scale | gdouble | Lecture/Ecriture | |
scale-set | gboolean | Lecture/Ecriture | |
size | gint | Lecture/Ecriture | |
size-points | gdouble | Lecture/Ecriture | |
size-set | gboolean | Lecture/Ecriture | |
stretch | PangoStretch | Lecture/Ecriture | |
stretch-set | gboolean | Lecture/Ecriture | |
strikethrough | gboolean | Lecture/Ecriture | |
strikethrough-set | gboolean | Lecture/Ecriture | |
style | PangoStyle | Lecture/Ecriture | |
style-set | gboolean | Lecture/Ecriture | |
text | gchararray | Lecture/Ecriture | |
underline | PangoUnderline | Lecture/Ecriture | |
underline-set | gboolean | Lecture/Ecriture | |
variant | PangoVariant | Lecture/Ecriture | |
variant-set | gboolean | Lecture/Ecriture | |
weight | gint | Lecture/Ecriture | |
weight-set | gboolean | Lecture/Ecriture |
GtkCellRendererToggle
Propriété | Type | Accès | Description |
activatable | gboolean | Lecture/Ecriture | |
active | gboolean | Lecture/Ecriture | |
inconsistent | gboolean | Lecture/Ecriture | |
radio | gboolean | Lecture/Ecriture |
GtkCellRenderPixbuf
Propriété | Type | Accès | Description |
pixbuf | GdkPixbuf | Lecture/Ecriture | |
pixbuf-expander-closed | GdkPixbuf | Lecture/Ecriture | |
pixbuf-expander-open | GdkPixbuf | Lecture/Ecriture | |
stock-detail | gchararray | Lecture/Ecriture | |
stock-id | gchararray | Lecture/Ecriture | |
stock-size | GtkIconSize | Lecture/Ecriture |
GtkTreeView
columns-changed |
Prototype fonction callback : void user_function(GtkTreeView
*treeview, gpointer user_data); Description : |
cursor-changed |
Prototype fonction callback : void user_function(GtkTreeView
*treeview, gpointer user_data); Description : |
expand-collapse-cursor-row |
Prototype fonction callback : gboolean user_function(GtkTreeView
*treeview, gboolean arg1, gboolean arg2, gboolean arg3, gpointer user_data); Description : |
move-cursor |
Prototype fonction callback : gboolean user_function(GtkTreeView
*treeview, GtkMovementStep arg1, gint arg2, gpointer user_data); Description : |
row-activated |
Prototype fonction callback : void user_function(GtkTreeView
*treeview, GtkTreePath *arg1, GtkTreeViewColumn *arg2, gpointer user_data); Description : |
row-collapsed |
Prototype fonction callback : void user_function(GtkTreeView
*treeview, GtkTreeIter *arg1, GtkTreePath *arg2, gpointer user_data); Description : |
row-expanded |
Prototype fonction callback : void user_function(GtkTreeView
*treeview, GtkTreeIter *arg1, GtkTreePath *arg2, gpointer user_data); Description : |
select-all |
Prototype fonction callback : gboolean user_function(GtkTreeView
*treeview, gpointer user_data); Description : |
select-cursor-parent |
Prototype fonction callback : gboolean user_function(GtkTreeView
*treeview, gpointer user_data); Description : |
select-cursor-row |
Prototype fonction callback : gboolean user_function(GtkTreeView
*treeview, gboolean arg1, gpointer user_data); Description : |
set-scroll-adjustments |
Prototype fonction callback : void user_function(GtkTreeView
*treeview, GtkAdjustment *arg1, GtkAdjustment *arg2, gpointer user_data); Description : |
start-interactive-search |
Prototype fonction callback : gboolean user_function(GtkTreeView
*treeview, gpointer user_data); Description : |
test-collapse-row |
Prototype fonction callback : gboolean user_function(GtkTreeView
*treeview, GtkTreeIter *arg1, GtkTreePath *arg2, gpointer user_data); Description : |
test-expand-row |
Prototype fonction callback : gboolean user_function(GtkTreeView
*treeview, GtkTreeIter *arg1, GtkTreePath *arg2, gpointer user_data); Description : |
toggle-cursor-row |
Prototype fonction callback : gboolean user_function(GtkTreeView
*treeview, gpointer user_data); Description : |
unselect-all |
Prototype fonction callback : gboolean user_function(GtkTreeView
*treeview, gpointer user_data); Description : |
GtkTreeViewColumn
clicked |
Prototype fonction callback : void user_function(GtkTreeViewColumn
*treeviewcolumn, gpointer user_data); Description : |
GtkCellRendererText
edited |
Prototype fonction callback : void user_function(GtkCellRendererText
*cellrenderertext, gchar *arg1, gchar *arg2, gpointer user_data); Description : |
GtkCellRendererToggle
toggled |
Prototype fonction callback : void user_function(GtkCellRendererToggle
*cellrenderertoggle, gchar *arg1, gpointer user_data); Description : |