GTK+ par l'exemple


précédentsommairesuivant

IV. Comment afficher plusieurs widgets

IV-A. Aperçu

Image non disponible

IV-B. Le problème

Dans la partie précédente, nous avons réussi à afficher un bouton dans la fenêtre de notre application. Si vous avez essayé d'ajouter un second widget, GTK+ à dû vous répondre poliment :

 
Sélectionnez
(gtk_box.exe:492) : Gtk-WARNING **: Attempting to add a widget with type
GtkButton to a GtkWindow, but as a GtkBin subclass a GtkWindow can only contain
one widget at a time; it already contains a widget of type GtkButton

Les plus anglophiles d'entre vous auront compris que GTK+ n'accepte pas l'ajout un second widget dans notre fenêtre tout simplement parce qu'il y en a déjà un et que la sous classe GtkBin (classe mère de notre GtkWindow) ne peut contenir qu'un seul widget.

IV-C. La solutions

Pour contourner ce problème, il faut commencer par créer un widget qui accepte d'en contenir plusieurs autres, pour ensuite y ajouter tout ce dont nous avons besoin. Pour l'instant, nous utiliserons qu'un seul widget (il existe trois classes qui permettent ceci), il s'agit des GtkBox. Il s'agit de la méthode que j'utilise le plus souvent. Ce n'est peut-être pas la plus simple à maîtriser mais elle extrêmement souple et puissante. Elle consiste à créer une boîte puis à y ajouter les widgets les uns après les autres (soit au début soit à la fin). Il existe deux classes héritant de GtkBox : les GtkVBox qui empilent les widgets dans le sens vertical et les GtkHBox qui font de même mais dans le sens horizontal. Les fonctions pour manipuler ces deux classes sont les mêmes, seule la fonction pour les créer portent un nom différent :

 
Sélectionnez
GtkWidget *gtk_vbox_new (gboolean homogeneous, gint spacing);
GtkWidget *gtk_hbox_new (gboolean homogeneous, gint spacing);

Le paramètre homogeneous permet de réserver pour chaque widget une zone de taille identique (zone que le widget n'est pas obligé de remplir) et spacing permet d'ajouter une bordure en pixels (espacement autour de la GtkBox). Ensuite, il suffit d'ajouter les différents widgets grâce aux fonctions :

 
Sélectionnez
void gtk_box_pack_start (GtkBox *box, GtkWidget *child, gboolean expand, gboolean fill, guint padding);
void gtk_box_pack_end (GtkBox *box, GtkWidget *child, gboolean expand, gboolean fill, guint padding);

Qui ajoutent réciproquement le widget child au début et à la fin de box. Le paramètre expand permet au widget d'avoir le plus de place possible (si le paramètre homogeneous vaut TRUE, cette option a aucun effet). Si plusieurs widget ont ce paramètre à TRUE, ils se partagent de façon égale l'espace. L'option fill permet au widget de remplir tout l'espace qui lui ait réservé.
Pour réellement comprendre l'influence de ces paramètres, il faut faire des tests en modifiant un à un chaque paramètre et observer les effets d'un redimentionnement de la fenêtre principale.
Le plus gênant avec cette méthode c'est qu'il faut jongler entre les GtkHBox et les GtkVBox en les imbriquant pour obtenir le résultat souhaiter : n'hésitez pas à utiliser une feuille et un crayon ;)

Pour en revenir à notre éditeur de texte, nous allons préparer notre application à contenir les futurs widgets. Nous utilisons un GtkVBox pour l'ensemble des widgets (il s'agit de la boîte principale qui pourra contenir d'autres GtkContainer selon nos besoins) :

main.c
Sélectionnez
#include <stdlib.h>
#include <gtk/gtk.h>
#include "callback.h"

int main (int argc, char **argv)
{
  GtkWidget *p_window = NULL;
  GtkWidget *p_main_box = 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);

  /* Creation du conteneur principal */
  p_main_box = gtk_vbox_new (FALSE, 0);
  gtk_container_add (GTK_CONTAINER (p_window), p_main_box);

  /* Creation du bouton "Quitter" */
  {
    GtkWidget *p_button = NULL;

    p_button = gtk_button_new_from_stock (GTK_STOCK_QUIT);
    g_signal_connect (G_OBJECT (p_button), "clicked", G_CALLBACK (cb_quit), NULL);
    gtk_box_pack_start (GTK_BOX (p_main_box), p_button, FALSE, FALSE, 0);
  }

  /* Affichage de la fenetre principale */
  gtk_widget_show_all (p_window);
  /* Lancement de la boucle principale */
  gtk_main ();
  return EXIT_SUCCESS;
}

IV-D. Code source


précédentsommairesuivant

  

Les sources présentées sur cette page sont libres de droits et vous pouvez les utiliser à votre convenance. Par contre, la page de présentation constitue une œuvre intellectuelle protégée par les droits d'auteur. Copyright © 2006-2008 Nicolas Joseph. Aucune reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents, images, etc. sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu'à trois ans de prison et jusqu'à 300 000 € de dommages et intérêts.