« Programmation GTK/Bonjour tout le monde pas à pas » : différence entre les versions

Contenu supprimé Contenu ajouté
STyx (discussion | contributions)
m wikifié
DCimarosa (discussion | contributions)
insertion source lang="C"
Ligne 2 :
 
Voici la fonction de rappel appelée lorsque le bouton est « clicked ». Dans notre exemple, on ignore le widget et les données mais il n'est pas difficile de faire quelque chose avec. Le prochain exemple utilisera le paramètre des données pour nous dire quel bouton a été pressé.
<source lang="C">
 
void hello (GtkWidget *widget, gpointer *data)
{
g_print ("Bonjour tout le monde\n");
}
</source>
 
Cette fonction de rappel est un peu spéciale. L'événement "delete_event" survient lorsque le gestionnaire de fenêtres l'envoie à l'application. On doit choisir ce qu'il faut faire de ces événements. On peut les ignorer, leur donner une réponse, ou simplement quitter l'application.
 
La valeur que l'on retourne dans cette fonction de rappel permet à GTK de savoir ce qu'il a à faire. En retournant <code>FALSE</code>, on l'informe que l'on ne veut pas que le signal "destroy" soit émis, afin de laisser notre application tourner. En retournant <code>TRUE</code>, on lui demande d'émettre "destroy" qui appellera à son tour notre gestionnaire du signal "destroy".
<source lang="C">
 
gint delete_event(GtkWidget *widget, GdkEvent *event, gpointer data)
{
Ligne 18 :
return (FALSE);
}
</source>
 
Voici une autre fonction de rappel qui ne fait que quitter l'application en appelant <code>gtk_main_quit()</code>. Il n'y a pas grand chose de plus à dire car elle est plutôt triviale :
<source lang="C">
 
void destroy (GtkWidget *widget, gpointer *data)
{
gtk_main_quit ();
}
</source>
 
Je suppose que vous connaissez la fonction <code>main()</code>... oui, comme les autres programmes C, toutes les applications GTK en ont une.
 
<source lang="C">
int main (int argc, char *argv[])
{
</source>
 
La partie qui suit déclare deux pointeurs sur des structures de type <code>GtkWidget</code>. Ceux-ci sont utilisés plus loin pour créer une fenêtre et un bouton.
<source lang="C">
 
GtkWidget *window;
GtkWidget *button;
</source>
 
Et revoici notre <code>gtk_init()</code>. Comme précédemment, il initialise le toolkit et analyse les paramètres de la ligne de commande. Il supprime chaque paramètre reconnu de la liste et modifie argc et argv pour faire comme si ces paramètres n'avaient jamais existé, laissant notre application analyser les paramètres restants.
<source lang="C">
 
gtk_init (&argc, &argv);
</source>
 
Création d'une nouvelle fenêtre. C'est plutôt classique. La mémoire est allouée pour une structure <code>GtkWidget</code> et window pointe donc sur celle-ci. Cela configure une nouvelle fenêtre, mais celle-ci ne sera pas affichée tant que l'on n'a pas appelé <code>gtk_widget_show(window)</code> vers la fin de notre programme.
<source lang="C">
 
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
</source>
 
Voici maintenant un exemple de connexion d'un gestionnaire de signal à un objet : la fenêtre. Le signal "destroy" est capturé. Il est émis lorsqu'on utilise le gestionnaire de fenêtres pour tuer la fenêtre (et que l'on retourne <code>TRUE</code> dans le gestionnaire "delete_event"), ou lorsqu'on utilise l'appel <code>gtk_widget_destroy()</code> en lui passant le widget window comme objet à détruire. Ici, on appelle juste la fonction <code>destroy()</code> définie ci-dessus avec le paramètre <code>NULL</code>, ce qui quitte GTK pour nous.
 
<code>GTK_OBJECT</code> et <code>GTK_SIGNAL_FUNC</code> sont des macros qui réalisent les conversions et les vérifications de types pour nous. Elles rendent aussi le code plus lisible.
<source lang="C">
 
gtk_signal_connect (GTK_OBJECT (window), "destroy",
GTK_SIGNAL_FUNC (destroy), NULL);
</source>
 
La fonction suivante sert à configurer un attribut d'un objet container. Elle configure simplement la fenêtre pour qu'elle ait une zone vide autour d'elle de 10 pixels de large où aucun widget ne pourra se trouver. Il existe d'autres fonctions similaires que nous verrons dans la section sur la Configuration des attributs des widgets
 
À nouveau, <code>GTK_CONTAINER</code> est une macro réalisant la conversion de type.
<source lang="C">
 
gtk_container_border_width (GTK_CONTAINER (window), 10);
</source>
 
Cet appel crée un nouveau bouton. Il alloue l'espace mémoire pour une nouvelle structure <code>GtkWidget</code>, l'initialise et fait pointer button vers elle. Ce bouton portera le label « Bonjour tout le monde » lorsqu'il sera affiché.
<source lang="C">
 
button = gtk_button_new_with_label ("Bonjour tout le monde");
</source>
 
Maintenant, prenons ce bouton et faisons lui faire quelque chose d'utile. On lui attache un gestionnaire de signal pour que, lorsqu'il émettra le signal "clicked", notre fonction <code>hello()</code> soit appelée. On ignore les paramètres et on ne passe donc que la valeur <code>NULL</code> à la fonction de rappel <code>hello()</code>. Évidemment, le signal "clicked" est émis lorsqu'on clique sur le bouton avec la souris.
<source lang="C">
 
gtk_signal_connect (GTK_OBJECT (button), "clicked",
GTK_SIGNAL_FUNC (hello), NULL);
</source>
 
On utilisera aussi ce bouton pour quitter notre programme, ce qui permettra d'illustrer la façon dont le signal "destroy" peut venir soit du gestionnaire de fenêtres, soit de notre programme. Quand le bouton est "clicked" comme cela est décrit plus haut, il appelle d'abord la fonction de rappel <code>hello()</code> puis celle-ci dans l'ordre dans lequel elles sont configurées. On peut avoir autant de fonctions de rappel que l'on désire, elles seront exécutées selon leur ordre de connexion. Puisque la fonction <code>gtk_widget_destroy()</code> n'accepte que <code>GtkWidget *widget</code> comme paramètre, on utilise ici la fonction <code>gtk_signal_connect_object()</code> à la place de <code>gtk_signal_connect()</code>.
<source lang="C">
 
gtk_signal_connect_object (GTK_OBJECT (button), "clicked",
GTK_SIGNAL_FUNC (gtk_widget_destroy),
GTK_OBJECT (window));
</source>
 
Voici un appel de placement, qui sera expliqué en détail plus tard, mais qui est plutôt facile à comprendre. Il indique simplement à GTK que le bouton doit être placé dans la fenêtre où il s'affichera.
<source lang="C">
 
gtk_container_add (GTK_CONTAINER (window), button);
</source>
 
Maintenant, nous avons tout configuré comme on le souhaitait : les gestionnaires de signaux sont en place et le bouton est mis dans la fenêtre où il doit se trouver. On demande alors à GTK de « montrer » les widgets à l'écran. Le widget window est affiché en dernier afin que la fenêtre entière surgisse d'un coup plutôt que voir d'abord la fenêtre s'afficher puis ensuite le bouton apparaître à l'intérieur. Il faut dire qu'avec des exemples simples comme celui-ci, vous ne ferez pas la différence.
<source lang="C">
 
gtk_widget_show(button);
 
gtk_widget_show (window);
</source>
 
Bien sûr, on appelle <code>gtk_main()</code> qui attendra les événements venant du serveur X et demandera aux widgets d'émettre les signaux lorsque ces événements surviendront.
<source lang="C">
 
gtk_main ();
</source>
 
Enfin, le return final. Il est exécuté lorsque <code>gtk_quit()</code> est appelé.
<source lang="C">
 
return 0;
</source>
 
Lorsque l'on clique sur un bouton GTK, le widget émet un signal "clicked". Afin de pouvoir utiliser cette information, notre programme configure un gestionnaire pour capturer ce signal. Ce gestionnaire appelle la fonction de notre choix. Dans notre exemple, lorsque le bouton que l'on a créé est "clicked", la fonction <code>hello()</code> est appelée avec le paramètre <code>NULL</code>, puis le gestionnaire suivant de ce signal est à son tour appelé. Il appelle la fonction <code>gtk_widget_destroy()</code> en lui passant le widget window comme paramètre, ce qui provoque la destruction de celui-ci. Ceci force la fenêtre à envoyer un signal "destroy", qui est capturé à son tour et appelle notre fonction de rappel <code>destroy()</code> qui ferme simplement GTK.