III. Fermer notre fenêtre grâce aux boutons▲
III-A. Aperçu▲
III-B. Les boutons poussoir▲
Maintenant que notre programme se termine proprement, il est plus convivial de proposer à l'utilisateur un bouton pour quitter. Pour créer un bouton poussoir, il existe plusieurs possibilités :
GtkWidget *
gtk_button_new (
void
);
GtkWidget *
gtk_button_new_with_label (
const
gchar *
label);
GtkWidget *
gtk_button_new_with_mnemonic (
const
gchar *
label);
GtkWidget *
gtk_button_new_from_stock (
const
gchar *
stock_id);
La première fonction crée un bouton qui peut servir pour contenir n'importe quel autre widget (label, image...). Si vous souhaitez créer un bouton avec du texte dessus, utilisez directement la seconde fonction qui prend en argument le texte à afficher. Si vous souhaitez ajouter un raccourci clavier (accessible avec la touche Alt), la troisième fonction permet d'en spécifier un en faisant précéder une lettre (généralement la première) d'un underscore '_' (si vous souhaitez afficher le caractère '_', il faut en mettre deux). Enfin la dernière fonction permet d'utiliser les Stock Items qui sont un ensemble d'éléments prédéfinis par GTK+ pour les menus et barres d'outils. Le seul paramètre de cette fonction est le nom de l'élément et GTK+ se charge d'afficher l'icône appropriée ainsi que le texte suivant la langue choisie et un raccourci.
C'est bien sûr cette dernière fonction que nous allons utiliser et ce le plus souvent possible. Voici le code pour créer un tel bouton :
GtkWidget *
p_button =
NULL
;
p_button =
gtk_button_new_from_stock (
GTK_STOCK_QUIT);
Pour obtenir tous les types de stocks items disponibles : GtkStockItem
Bien sûr, comme pour la fenêtre si l'on veut voir quelque chose, il faut demander à GTK+ d'afficher notre widget :
gtk_widget_show (
p_button);
Mais pas seulement ! En effet, il faut préciser à GTK+ où doit être affiché notre bouton. Pour cela, la classe GtkWindow est dérivée de la classe GtkContainer qui est, comme son nom le laisse penser, un conteneur pour widget. Pour ajouter un widget, il suffit de faire appel à la fonction gtk_container_add :
void
gtk_container_add (
GtkContainer *
container, GtkWidget *
widget);
Le premier paramètre de cette fonction est un GtkContainer, or nous souhaitons passer notre fenêtre qui est un GtkWidget, pour ne pas avoir de problèmes, il faut utiliser le système de macro offert par GTK+ pour transtyper notre GtkWidget en GtkContainer (eh oui en C, le polymorphisme a ses limites) :
gtk_container_add (
GTK_CONTAINER (
p_window), p_button);
Ce mécanisme de transtypage permet à GTK+ de vérifier que notre GtkWidget est bien compatible avec l'utilisation que l'on souhaite en faire. En cas d'échec, GTK+ nous prévient en affichant un message dans la console :
(gtk_bouton.exe:1044): Gtk-CRITICAL **: gtk_container_add: assertion `GTK_IS_CONTAINER (container)' failed
Pour finir, il faut connecter notre bouton pour appeler notre fonction cb_quit lorsque l'utilisateur clic dessus (ce qui correspond à l'événement "clicked") :
g_signal_connect (
G_OBJECT (
p_button), "
clicked
"
, G_CALLBACK (
cb_quit), NULL
);
Pour éviter d'appeler la fonction gtk_widget_show pour tous les widgets de notre application, on peut se contenter d'un seul appel à la fonction gtk_widget_show_all qui permet d'afficher tous les widgets contenus dans celui passé à la fonction.
#include <stdlib.h>
#include <gtk/gtk.h>
#include "callback.h"
int
main (
int
argc, char
**
argv)
{
GtkWidget *
p_window =
NULL
;
/* Initialisation de GTK+ */
gtk_init (&
argc, &
argv);
/* Creation de la fenetre principale de notre application */
p_window =
gtk_window_new (
GTK_WINDOW_TOPLEVEL);
g_signal_connect (
G_OBJECT (
p_window), "
destroy
"
, G_CALLBACK (
cb_quit), NULL
);
{
GtkWidget *
p_button =
NULL
;
p_button =
gtk_button_new_from_stock (
GTK_STOCK_QUIT);
gtk_container_add (
GTK_CONTAINER (
p_window), p_button);
g_signal_connect (
G_OBJECT (
p_button), "
clicked
"
, G_CALLBACK (
cb_quit), NULL
);
}
/* Affichage de la fenetre principale */
gtk_widget_show_all (
p_window);
/* Lancement de la boucle principale */
gtk_main (
);
return
EXIT_SUCCESS;
}