Programmation GTK2 en Pascal/GtkNotebook
Programmation GTK2 en Pascal |
|
Présentation
modifierNous 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 GtkContainer
.
Hiérarchie
modifierHiérarchie |
GObject └─GtkObject └─GtkWidget └─GtkContainer └─GtkNotebook |
Utilisation de base
modifierCréation
modifierPour 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
modifierNous 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, notebook
, est bien sûr le GtkNotebook
dans lequel nous voulons ajouter la page. Il faudra utiliser la fonction de conversion GTK_NOTEBOOK().
Le second, child
, est le contrôle qui sera inséré dans la nouvelle page, et le troisième, tab_label
, le contrôle qui sera affiché dans l'onglet.
La troisième fonction demande un paramètre supplémentaire, position
, 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
modifierNous 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 GtkNotebook
. 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 child
, 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 page_num
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
modifierNous 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 Pgchar
. Cette fonction fonctionnera correctement uniquement si le label de la page est un GtkLabel
, 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 GtkLabel
. 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 GtkLabel
. Cette fonction s'occupe de la création du GtkLabel
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 tab_text
ou tab_label
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
modifierNous allons maintenant voir comment modifier trois des propriétés d'un GtkNotebook
.
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 :
- GTK_POS_LEFT pour les mettre à gauche ;
- GTK_POS_RIGHT pour les mettre à droite ;
- GTK_POS_TOP pour les mettre en haut ;
- GTK_POS_BOTTOM pour les mettre en bas.
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 show_tabs
à 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 scrollable
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
modifierNous allons créer un programme qui insèrera un GtkNotebook
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 gtk009.pas
:
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
modifierLa fonction g_strdup_printf
permet de faire des manipulations sur les chaines de caractères gérées par Gtk+ de type PGChar
. Elle est identique au niveau manipulation à la fonction Format
hormis qu'elle réserve de l'espace mémoire qu'il faut libérer après utilisation par la fonction g_free
.
Les fonction préfixées par un « g_ » sont des fonctions de la GLib.
Exécution
modifierVoilà ce que donne l'exécution du programme gtk009
:
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 ».
Conteneurs : GtkContainer ~ GtkBox ~ GtkBin — GtkHBox ~ GtkVBox ~ GtkTable ~ GtkNotebook |