Présentation.
Nous allons étudier dans ce chapitre les pages à onglets qui sont souvent utilisés dans les fenêtres de configuration. Pour cela nous allons utiliser le contrôle GtkNotebook qui dérive du contrôle codice_1.
Utilisation de base.
Création.
Pour ne pas changer la création du contrôle en lui-même est très simple :
 function gtk_notebook_new : PGtkWidget;
Maintenant que notre contrôle est créé, nous allons lui ajouter des pages.
Insertion de pages.
Nous avons là aussi trois fonctions qui restent très classiques :
 procedure gtk_notebook_append_page(notebook : PGtkNotebook; child : PGtkWidget; tab_label : PGtkWidget);
 procedure gtk_notebook_prepend_page(notebook : PGtkNotebook; child : PGtkWidget; tab_label : PGtkWidget);
 procedure gtk_notebook_insert_page(notebook : PGtkNotebook; child : PGtkWidget; tab_label : PGtkWidget;
 position : gint);
La première fonction ajoute une nouvelle page à onglet à la suite des autres, la deuxième fonction l'ajoute au début, et la dernière l'ajoute à une position particulière.
Le premier paramètre, codice_2, est bien sûr le codice_3 dans lequel nous voulons ajouter la page. Il faudra utiliser la fonction de conversion GTK_NOTEBOOK().
Le second, codice_4, est le contrôle qui sera inséré dans la nouvelle page, et le troisième, codice_5, le contrôle qui sera affiché dans l'onglet.
La troisième fonction demande un paramètre supplémentaire, codice_6, qui est la position à laquelle il faut ajouter la page. Si la valeur n'est pas correcte (négative ou trop grande) la page sera ajoutée à la suite des autres.
Gestion des pages.
Nous allons maintenant voir les fonctions qui permettent de connaître le nombre de page, la page en cours ainsi que d'autres fonctions.
Tout d'abord, la fonction suivante permet de connaître le nombre total de pages contenus dans le codice_3. "Bizarrement cette fonction n'existe pas dans les déclarations de gtk2forpascal ! Pour l'utiliser, il faudra donc la déclarer manuellement" :
 function gtk_notebook_get_n_pages(notebook : PGtkNotebook) : gint; cdecl; external gtklib;
Ensuite, pour connaître le numéro de la page courante, nous avons cette fonction :
 function gtk_notebook_get_current_page(notebook : PGtkNotebook) : gint;
Par contre pour connaître le numéro d'une autre page que la courante, il faudra utiliser cette fonction :
 function gtk_notebook_page_num(notebook : PGtkNotebook; child : PGtkWidget) : gint;
Cette fonction permet d'obtenir le numéro de la page contenant le contrôle codice_4, ce qui impose donc d'avoir garder une trace de ce contrôle pour pouvoir utiliser cette fonction.
Avec un numéro de page, nous allons pouvoir récupérer un pointeur sur le contrôle qui est contenu dans la page avec cette fonction :
 function gtk_notebook_get_nth_page(notebook : PGtkNotebook; page_num : gint) : PGtkWidget;
Ou bien nous allons pouvoir tout simplement supprimer la page :
 procedure gtk_notebook_remove_page(notebook : PGtkNotebook; page_num : gint);
Et pour terminer, voici trois fonctions de navigation :
 procedure gtk_notebook_next_page(notebook : PGtkNotebook);
 procedure gtk_notebook_prev_page(notebook : PGtkNotebook);
 procedure gtk_notebook_set_current_page(notebook : PGtkNotebook; page_num : gint);
La première fonction passe de la page courante à la page suivante. Si la dernière page est déjà affichée, il ne se passera rien. La deuxième fonction, elle, passe de la page courante à la page précédente. Bien entendu, si la page courante est déjà la première cette fonction n'aura aucun effet. La dernière fonction quant à elle passe directement à une page précise. Si la valeur de codice_9 est négative, nous passerons à la dernière page, par contre si cette valeur est trop grande, aucune action ne sera faite.
Gestion des labels.
Nous allons maintenant voir comment modifier ou récupérer le label d'une page. Attention pour chacune de ces fonctions, il faut connaître le contrôle contenu dans la page.
Tout d'abord, pour récupérer le label de la page, il existe deux fonctions différentes :
 function gtk_notebook_get_tab_label_text(notebook : PGtkNotebook; child : PGtkWidget) : Pgchar;
 function gtk_notebook_get_tab_label(notebook : PGtkNotebook; child : PGtkWidget) : PGtkWidget;
La première fonction renvoie directement le label de la page sous la forme d'un codice_10. Cette fonction fonctionnera correctement uniquement si le label de la page est un codice_11, car comme nous l'avons vu lors de l'étude des fonctions d'insertion des pages, il est possible de définir le label comme autre chose qu'un codice_11. Dans ce cas, il faut utiliser la deuxième fonction qui elle renvoie le contrôle qui a été utilisé lors de la création.
Pour définir un nouveau label pour une page, il existe là aussi deux fonctions :
 procedure gtk_notebook_set_tab_label_text(notebook : PGtkNotebook; child : PGtkWidget; tab_text : Pgchar);
 procedure gtk_notebook_set_tab_label(notebook : PGtkNotebook; child : PGtkWidget; tab_label : PGtkWidget);
La première fonction permet de définir un label de type codice_11. Cette fonction s'occupe de la création du codice_11 et de son insertion dans l'onglet de la page. La deuxième fonction permet d'insérer n'importe quel contrôle dans l'onglet, comme pour les fonctions de création. Dans les deux cas, si les paramètres codice_15 ou codice_5 sont définis comme NULL, le label de la page sera « Page y », y étant le numéro de la page.
Modification des propriétés des onglets.
Nous allons maintenant voir comment modifier trois des propriétés d'un codice_3. 
Tout d'abord voyons comment gérer la position des onglets :
 procedure gtk_notebook_set_tab_pos(notebook : PGtkNotebook; pos : TGtkPositionType);
 function gtk_notebook_get_tab_pos(notebook : PGtkNotebook) : TGtkPositionType;
La première fonction permet de modifier la position des onglets. C'est le paramètre pos qui définit sa position, et il doit prendre une des valeurs suivantes :
La deuxième fonction permet au contraire de connaître la position des onglets. La valeur de retour est obligatoirement une des quatre valeurs précédentes.
Ensuite nous allons pouvoir définir si les onglets doivent s'afficher ou pas avec ces fonctions :
 procedure gtk_notebook_set_show_tabs(notebook : PGtkNotebook; show_tabs : gboolean);
 function gtk_notebook_get_show_tabs(notebook : PGtkNotebook) : gboolean;
Si nous voulons modifier ce paramètre, il faut utiliser la première fonction en mettant le paramètre codice_18 à TRUE pour les afficher et à FALSE dans le cas contraire. La deuxième fonction permet quant à elle de connaître l'état de cette propriété.
Et enfin, pour terminer nous allons voir comment ajouter deux boutons de navigation à la fin des onglets, pour le cas où il y aurait trop d'onglets à afficher :
 procedure gtk_notebook_set_scrollable(notebook : PGtkNotebook; scrollable : gboolean);
 function gtk_notebook_get_scrollable(notebook : PGtkNotebook) : gboolean;
Si nous mettons le paramètre codice_19 de la première fonction à TRUE, deux boutons de navigation apparaîtront et une partie seulement des onglets sera affichée. Pour accéder aux autres onglets il faudra utiliser ces nouveaux boutons.
Bien entendu, la deuxième fonction permet de savoir si les boutons de navigation sont présents ou pas.
Programme exemple.
Nous allons créer un programme qui insèrera un codice_3 de 8 pages dans une fenêtre. Chaque page contiendra uniquement un label « Je suis le GtkLabel numero x ». Il y a aussi un bouton qui permettra d'afficher les informations de la page sélectionnée dans une boîte de dialogue.
Voilà le fichier codice_21 :
 program gtk009;
 uses glib2, gtk2, SysUtils;
 procedure OnBoutonClick(ABouton : PGtkwidget; AData : pgpointer); cdecl;
 var
 pDialogue : PGtkWidget;
 pContEnfant : PGtkWidget;
 NoPage : GInt;
 TexteLabel : PGChar;
 TexteOnglet : PGChar;
 TexteDialogue : PGChar;
 begin
 // Récuperation de la page active 
 NoPage := gtk_notebook_get_current_page(GTK_NOTEBOOK(AData));
 // Récuperation du contrôle enfant 
 pContEnfant := gtk_notebook_get_nth_page(GTK_NOTEBOOK(AData), NoPage);
 // Récuperation du label 
 TexteLabel := gtk_label_get_text(GTK_LABEL(pContEnfant));
 // Récuperation du label de l'onglet
 TexteOnglet := gtk_notebook_get_tab_label_text(GTK_NOTEBOOK(AData), pContEnfant);
 // Création du label de la boite de dialogue 
 TexteDialogue := g_strdup_printf('C' 'est la page %d'#13#10 +
 'Le label est "%s"'#13#10 +
 'Le label de l' 'onglet est "%s"',
 [NoPage, TexteLabel, TexteOnglet]);
 pDialogue := gtk_message_dialog_new(NULL,
 GTK_DIALOG_MODAL,
 GTK_MESSAGE_INFO,
 GTK_BUTTONS_OK,
 TexteDialogue);
 gtk_dialog_run(GTK_DIALOG(pDialogue));
 gtk_widget_destroy(pDialogue);
 g_free(TexteDialogue);
 end;
 var
 pFenetre : PGtkWidget;
 pVBox : PGtkWidget;
 pNotebook : PGtkWidget;
 pBouton : PGtkWidget;
 I : gint;
 pLabel : PGtkWidget;
 pTabLabel : PGtkWidget;
 TexteLabel : PGChar;
 TexteOnglet : PGChar;
 begin
 gtk_init(@argc, @argv);
 pFenetre := gtk_window_new(GTK_WINDOW_TOPLEVEL);
 gtk_window_set_position(GTK_WINDOW(pFenetre), GTK_WIN_POS_CENTER);
 gtk_window_set_default_size(GTK_WINDOW(pFenetre), 320, 200);
 gtk_window_set_title(GTK_WINDOW(pFenetre), 'Gtk009 : GtkNoteBook');
 gtk_signal_connect(pGTKOBJECT(pFenetre), 'destroy', GTK_SIGNAL_FUNC(@gtk_main_quit), NULL);
 // Création de la GtkVBox et ajout dans la fenêtre
 pVBox := gtk_vbox_new(FALSE, 0);
 gtk_container_add(GTK_CONTAINER(pFenetre), pVBox);
 // Au tour du bouton
 pBouton := gtk_button_new_with_label('Informations');
 gtk_box_pack_start(GTK_BOX(pVBox), pBouton, FALSE, FALSE, 0);
 // Creation du GtkNotebook 
 pNotebook := gtk_notebook_new;
 gtk_box_pack_start(GTK_BOX(pVBox), pNotebook, TRUE, TRUE, 0);
 // Position des onglets : en bas 
 gtk_notebook_set_tab_pos(GTK_NOTEBOOK(pNotebook), GTK_POS_BOTTOM);
 // Ajout des boutons de navigation 
 gtk_notebook_set_scrollable(GTK_NOTEBOOK(pNotebook), TRUE);
 // Création de chacune des pages d'onglet
 for I := 1 to 8 do begin
 TexteLabel := g_strdup_printf('Je suis le GtkLabel numéro %d', [I]);
 TexteOnglet := g_strdup_printf('Page %d', [I]);
 // Création des différents GtkLabel 
 pLabel := gtk_label_new(TexteLabel);
 pTabLabel := gtk_label_new(TexteOnglet);
 // Insertion de la page 
 gtk_notebook_append_page(GTK_NOTEBOOK(pNotebook), pLabel, pTabLabel);
 g_free(TexteLabel);
 g_free(TexteOnglet);
 end;
 g_signal_connect(pGTKOBJECT(pBouton), 'clicked', GTK_SIGNAL_FUNC(@OnBoutonClick), pNotebook);
 gtk_widget_show_all(pFenetre);
 gtk_main;
 end.
Note.
La fonction codice_22 permet de faire des manipulations sur les chaines de caractères gérées par Gtk+ de type codice_23. Elle est identique au niveau manipulation à la fonction codice_24 hormis qu'elle réserve de l'espace mémoire qu'il faut libérer après utilisation par la fonction codice_25.
Les fonction préfixées par un « g_ » sont des fonctions de la GLib.
Exécution.
Voilà ce que donne l'exécution du programme codice_26 :
Si on clique sur le petit triangle noir à droite pour aller jusqu'à la page 6 :
Et on clique sur le bouton « Informations » :
Nota : En interne, les pages sont numérotées à partir de 0 (comme bien souvent en informatique). C'est pour cela que l'affichage débute par « C'est la page 5 ».