/* Création de 5 autres labels. Cette fois-ci, on utilise
 * gtk_list_item_new_with_label(). On ne peut interroger la chaîne
 * des labels car on n'a pas les pointeurs de labels et on associe
 * donc simplement le list_item_data_key de chaque item ayant la même 
 * chaîne de texte pour l'ajouter au items que l'on place dans une liste
 * doublement chaînée (GList). On les ajoute alors par un simple appel à
 * gtk_list_append_items().
 * Comme on utilise g_list_prepend() pour mettre les items dans la liste
 * doublement chaînée, leur ordre sera décroissant (au lieu d'être croissant si
 * on utilisait g_list_append()). */
 dlist=NULL;
 for (; i<10; i++) {
 sprintf(buffer, "Item avec le label %d", i);
 list_item=gtk_list_item_new_with_label(buffer);
 dlist=g_list_prepend(dlist, list_item);
 gtk_widget_show(list_item);
 gtk_object_set_data(GTK_OBJECT(list_item),
 list_item_data_key,
 "Item avec label intégré");
 gtk_list_append_items(GTK_LIST(gtklist), dlist);
 /* Enfin, on veut voir la fenêtre... */
 gtk_widget_show(window);
 /* Lancement de la boucle principale de gtk */
 gtk_main();
 /* On arrive ici après que gtk_main_quit() ait été appelée lorsque
 * la fenêtre principale a été détruite. */
 /* Gestionnaire de signal connecté aux événements boutons presser/relâcher
 * du GtkList. */
 void
 sigh_button_event (GtkWidget *gtklist,
 GdkEventButton *event,
 GtkWidget *frame)
 /* On ne fait quelque chose que si le troisième bouton (celui de droite) a été
 * relâché. */
 if (event->type==GDK_BUTTON_RELEASE &&
 event->button==3) {
 GList *dlist, *free_list;
 GtkWidget *new_prisoner;
 /* On recherche l'item sélectionné à ce moment précis. 
 * Ce sera notre prisonnier ! */
 dlist=GTK_LIST(gtklist)->selection;
 if (dlist)
 new_prisoner=GTK_WIDGET(dlist->data);
 else
 new_prisoner=NULL;
 /* On recherche les items déjà prisonniers et on les
 * remet dans la liste.
 * Il ne faut pas oublier de libérer la liste doublement
 * chaînée que gtk_container_children() retourne. */
 dlist=gtk_container_children(GTK_CONTAINER(frame));
 free_list=dlist;
 while (dlist) {
 GtkWidget *list_item;
 list_item=dlist->data;
 gtk_widget_reparent(list_item, gtklist);
 dlist=dlist->next;
 g_list_free(free_list);
 /* Si l'on a un nouveau prisonnier, on l'ôte du GtkList et on le place
 * dans le cadre « Prison ». On doit désélectionner l'item avant.*/
 if (new_prisoner) {
 GList static_dlist;
 static_dlist.data=new_prisoner;
 static_dlist.next=NULL;
 static_dlist.prev=NULL;
 gtk_list_unselect_child(GTK_LIST(gtklist),
 new_prisoner);
 gtk_widget_reparent(new_prisoner, frame);

/* Gestionnaire de signal appelé lorsque le GtkList
 * émet le signal "selection_changed". */
 void
 sigh_print_selection (GtkWidget *gtklist,
 gpointer func_data)
 GList *dlist;
 /* Recherche dans la liste doublement chaînée des items sélectionnés
 * du GtkList, à faire en lecture seulement ! */
 dlist=GTK_LIST(gtklist)->selection;
 /* S'il n'y a pas d'items sélectionné, il n'y a rien d'autre à faire que
 * de le dire à l'utilisateur. */
 if (!dlist) {
 g_print("Sélection nettoyée\n");
 return;
 /* Ok, on a une sélection et on l'affiche. */
 g_print("La sélection est ");
 /* On récupère l'item dans la liste doublement chaînée 
 * puis on interroge la donnée associée par list_item_data_key
 * et on l'affiche. */
 while (dlist) {
 GtkObject *list_item;
 gchar *item_data_string;
 list_item=GTK_OBJECT(dlist->data);
 item_data_string=gtk_object_get_data(list_item,
 list_item_data_key);
 g_print("%s ", item_data_string);
 dlist=dlist->next;
 g_print("\n");

Programmation GTK/Widget item de liste
Le widget GtkListItem sert de container pour contenir un fils, lui fournissant des fonctions de sélection/déséselection exactement comme le widget GtkList les demande pour ses fils.
Un GtkListItem a sa propre fenêtre pour recevoir les événements et a sa propre couleur de fond, habituellement blanche.
Comme il est directement dérivé d'un GtkItem, il peut être traité comme tel en utilisant la macro GTK_ITEM(ListItem), reportez-vous à la section sur le widget GtkItem pour plus de détail sur celui-ci. Habituellement, un GtkListItem contient juste un label pour identifier, par exemple, un nom de fichier dans un GtkList -- la fonction appropriée gtk_list_item_new_with_label() est donc fournie. Le même effet peut être obtenu en créant un GtkLabel à part, en configurant son alignement avec xalign=0 et yalign=0.5 suivi d'un ajout ultérieur au GtkListItem.
Tout comme on n'est pas forcé d'ajouter un GtkLabel à un GtkListItem, on peut aussi ajouter un GtkVBox ou un GtkArrow etc. à un GtkListItem.

Programmation GTK/Présentation
Dans cette section, nous construirons un programme simple de dessin. Ce faisant, nous examinerons comment gérer les événements souris, comment dessiner dans une fenêtre, et comment mieux dessiner en utilisant un pixmap en arrière plan. Après avoir créé ce programme, nous l'étendrons en lui ajoutant le support des périphériques Xinput, comme les tables de tracé. GTK dispose de routines de support qui facilitent beaucoup l'obtention des informations étendues (comme la pression et l'inclinaison du stylet) à partir de tels périphériques.