Créer une interface graphique avec Glade3 et GtkBuilder

Franck Hecht

GTK+ permet la création d'interface graphique en langage C cependant, la programmation de grandes interfaces se révèle souvent très longue et fastidieuse. Glade est un outil (RAD - Rapid Application Programing) qui permet de gagner un temps considérable. Dans sa version 3, il génère un fichier XML à la place du code, nous allons voir dans ce tutoriel comment utiliser Glade3 conjointement avec GtkBuilder !

Commentez cet article : Commentez ♪

- Titre : Créer une interface graphique avec Glade3 et GtkBuilder

- Auteur : Franck Hecht

- Parution : 27 septembre 2008

- Licence : Copyright ® 2008 Franck Hecht. 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.

Sommaire

- I. Création d'une interface basique avec Glade 3

- II. Installation de Python

- III. Conversion du fichier XML de Glade 3

- IV. Chargement de l'interface par le code

- V. Résumé

- VI. Téléchargement

- VII. Remerciements

I - Création d'une interface basique avec Glade 3

Glade 3 se présente cette fois sous une seule et même fenêtre contrairement aux versions précédentes. Son interface se décompose en trois parties (de gauche à droite suivant l'image ci-dessus) :

- Le panneau des widgets GTK+ qu'on peut insérer dans nos fenêtres

- La zone de travail où on pose une fenêtre et les autres widgets

- La liste des widgets affichés par hiérarchie qu'on a déjà posés et en dessous, les propriétés du widget sélectionné

Le but de notre petit programme d'exemple consistera à créer une fenêtre avec une zone de texte et deux boutons, le premier bouton Ok affichera le contenu de la zone de texte dans une boîte de message et le bouton Annuler quittera simplement le programme. Cette partie du tutoriel est en vidéo au format flash, vous la trouverez ci-dessous...

Si vous ne disposez par encore de Glade 3, vous pouvez le télécharger sur différents sites suivant votre système d'exploitation :

- http://gladewin32.sourceforge.net/(pour Windows)

- http://glade.gnome.org/(pour Linux)

II - Installation de Python

Le fichier XML *.glade créé par Glade 3 ne peut être utilisable directement avec GtkBuilder, il faut donc le transformer pour GTK+ ce qui se fait avec un script fourni avec la bibliothèque.

Le script étant écrit en Python, il faut donc ce langage d'installé, si vous l'avez déjà installé, vous pouvez passer au chapitre suivant.

Vous pouvez télécharger Python depuis le site officiel à cette adresse : http://www.python.org/download/(téléchargez la dernière version) puis installez-le.

Pour les utilisateurs de Windows, une fois Python installé, ajoutez le chemin des fichiers exécutables dans la variable d'environnement PATH. Allez dans le Panneau de Configuration puis cliquez sur l'icône Système puis allez dans les Paramètres système avancés.

Cliquez ensuite sur le bouton Variables d'environnement puis dans la partie Variables système, modifiez la variable Path en ajoutant le chemin d'installation de Python : ;C:\Python25(le chemin commence par un ; car chaque chemin dans la variable doit être séparé par ce caractère !).

III - Conversion du fichier XML de Glade 3

Pour convertir le fichier XML créé par Glade 3, il faut utiliser le script Python gtk-builder-convert fournit avec GTK+.

Ouvrez votre fenêtre de ligne de commande (sous Windows, Démarrez->Exécuter->cmd.exe puis tapez la suite de commandes python gtk-builder-convert puis le nom du fichier *.glade et un nom avec l'extension *.xml par exemple, dans le cas du fichier TutorielGladeGtk.glade créé au Chapitre I (le chemin n'est pas forcément le même que le mien) :

python "c:\Program Files\CodeBlocks\MinGW\bin\gtk-builder-convert" TutorielGladeGtk.glade interface.xml

Dans mon cas, l'installation de GTK+ est faite manuellement dans les répertoires de Code::Blocks, le script se trouve donc dans le répertoire bin de MingW qui est la suite de compilation GCC pour Windows, vous devrez sans doute adapter cette ligne de commande par rapport à votre installation !

IV - Chargement de l'interface par le code

Maintenant que nous avons notre interface dans un fichier XML compréhensible par GtkBuilder, il nous faut la charger par le biais du code qui devient alors très court.

Il faut commencer par initialiser un pointeur de type GtkBuilder avec la fonction gtk_builder_new puis ensuite, charger le fichier XML avec la fonction gtk_builder_add_from_file

A partir de là, nous pouvons récupérer des pointeurs sur les différents widgets de l'interface par le biais de la fonction gtk_builder_get_object pour un widget particulier ou bien gtk_builder_get_objects pour récupérer la liste de tous les widgets !

Voici un exemple de code qui charge notre interface du fichier interface.xml :

#include <stdlib.h>
#include <gtk/gtk.h>

static void cb_ok (GtkWidget * p_wid, gpointer p_data)
{
GtkWidget   * p_dialog  = NULL;
const char  * p_text    = p_data;

if (p_text != NULL)
{
p_dialog = gtk_message_dialog_new (
NULL,
GTK_DIALOG_MODAL,
GTK_MESSAGE_INFO,
GTK_BUTTONS_OK,
p_text
);

gtk_dialog_run (GTK_DIALOG (p_dialog));
gtk_widget_destroy (p_dialog);
}
}

static void cb_quit (GtkWidget * p_wid, gpointer p_data)
{
gtk_main_quit ();
}

int main (int argc, char ** argv)
{
GtkBuilder  *  p_builder   = NULL;
GError      *  p_err       = NULL;

/* Initialisation de GTK+ */
gtk_init (& argc, & argv);

/* Creation d'un nouveau GtkBuilder */
p_builder = gtk_builder_new ();

if (p_builder != NULL)
{
/* Chargement du XML dans p_builder */
gtk_builder_add_from_file (p_builder, "interface.xml", & p_err);

if (p_err == NULL)
{
/* 1.- Recuparation d'un pointeur sur la fenetre. */
GtkWidget * p_win = (GtkWidget *) gtk_builder_get_object (
p_builder, "window1"
);

/* 2.- */
/* Signal du bouton Ok */
g_signal_connect (
gtk_builder_get_object (p_builder, "button1"),
"clicked", G_CALLBACK (cb_ok),
(gpointer) gtk_entry_get_text (
GTK_ENTRY (gtk_builder_get_object (p_builder, "entry1"))
)
);

/* Signal du bouton Annuler */
g_signal_connect (
gtk_builder_get_object (p_builder, "button2"),
"clicked", G_CALLBACK (cb_quit), NULL
);

gtk_widget_show_all (p_win);
gtk_main ();
}
else
{
/* Affichage du message d'erreur de GTK+ */
g_error ("%s", p_err->message);
g_error_free (p_err);
}
}

return EXIT_SUCCESS;
}

Vous pouvez remarquer en 1, qu'un pointeur sur la fenêtre principale est récupéré, ceci est obligatoire pour pouvoir afficher la fenêtre ! Comme vous le voyez, il faut aussi transtyper le retour de la fonction gtk_builder_get_object car celle-ci renvoie un pointeur de type GObject.

En 2 nous assignons des callbacks pour chacun des boutons. Nous ne gardons pas ici de pointeur sur les widgets, on passe directement le retour de la fonction gtk_builder_get_object, ce qui est suffisant dans ce cas !

Dans le signal pour le bouton Ok(button1), on passe en dernier argument un pointeur sur le texte contenu dans le GtkEntry entry1, texte que nous affichons dans une boîte de message.

Le nom des widgets à passer à la fonction gtk_builder_get_object est le nom tel que vous l'avez défini dans Glade, pour cette raison, il est préférable de donner des noms assez explicites aux widgets !

Il est également possible de configurer les callbacks dans Glade3, il faut pour cela se rendre dans l'onglet Signaux dans les propriétés du widget sélectionné. Pour la compilation, il faut ajouter les options:

-Wl,--export-dynamic

V - Résumé

Glade3 et GtkBuilder peuvent faire gagner un temps considérable sur de grands développements où il faut écrire des interfaces graphiques complexes. Vous pouvez trouver tout ce qui concerne GtkBuilder et ses fonctions dans la documentation officielle : http://library.gnome.org/devel/gtk/stable/GtkBuilder.html

VI - Téléchargement

Vous pouvez télécharger le code source et le fichier XML ici

VII - Remerciements

Merci à RideKick pour sa relecture et correction de ce tutoriel. Merci également à gege2061, buchs et loka d'avoir suivi de près l'élaboration du tutoriel et de m'avoir permis de l'améliorer ;)