I. Introduction▲
I-A. But de ce tutoriel▲
Pour vous initier aux joies de la programmation d'interfaces graphiques, plutôt que de faire un catalogue de toutes les fonctions de la bibliothèque, ce qui serait long et vite ennuyeux, je vous propose de construire pas à pas une application : un éditeur de texte. Pas un simple éditeur de texte, histoire de faire le tour des possibilités de GTK+, nous allons y ajouter pas à pas les fonctionnalités suivantes :
- création, ouverture, enregistrement de fichiers textes ;
- possibilité d'ouvrir plusieurs fichiers grâce à une navigation par onglets ;
- ouverture rapide d'un fichier grâce à une liste de fichiers.
Rien d'impressionnant par rapport à un traitement de texte, mais plus évolué et plus pratique qu'un simple éditeur de texte. Ce tutoriel est organisé de façon à ajouter une nouvelle fonctionnalité à chaque étape tout en apprenant à maîtriser un ou plusieurs éléments de GTK+.
Comme je viens de le dire, il n'est pas question de faire un catalogue de la bibliothèque, cependant avant d'utiliser un nouveau type de widget, j'en ferai une brève description qui pourra vous servir de pense-bête lors de vos futurs développements. Cette description comportera un aperçu pour les widgets graphiques, sa hiérarchie d'héritage, ses fonctions de créations (constructeurs), les fonctions les plus utilisées et les signaux importants de la classe.
I-B. Connaissances requises▲
Le but de ce tutoriel est d'apprendre à maîtriser GTK+ en partant de zéro, ou presque, en effet avant de vouloir créer une interface graphique, il vaut mieux bien connaître le langage C en mode console. Pour cela je vous renvoie au cours de la rubrique C.
I-C. Quelques mots sur GTK+▲
I-C-1. Historique▲
GTK+ ou the GIMP Toolkit était à l'origine une boîte à outils pour les développeurs du logiciel the GIMP (the GNU Image Manipulation Program), qui comme son nom l'indique est un logiciel de manipulation d'images rattaché au projet GNU. Au vu de l'importance de cette boîte à outils, GTK+ a été détaché de the GIMP en septembre 1997. Depuis il existe deux versions : GTK+ 1.0 et GTK+ 2.0, versions qui ne sont pas totalement compatibles cependant la première est encore utilisée dans certaines applications, tel que dans le domaine de l'embarqué du fait de sa complexité moindre. Il est bien évident que c'est la seconde version qui est la plus utilisée, elle est à l'origine de nombreux projets tels que le gestionnaire de fenêtre GNOME (GNU Network Object Model Environment). La dernière version en date est la 2.8.1 annoncée le 24 août 2005.
I-C-2. Structure▲
Comme précisé précédemment, GTK+ est une boîte à outils et, en tant que tel, elle est constituée de plusieurs bibliothèques indépendantes développées par l'équipe de GTK+.
- La GLib propose un ensemble de fonctions qui couvrent des domaines aussi vastes que les structures de données, la gestion des threads et des processus de façon portable ou encore un analyseur syntaxique pour les fichiers XML et bien d'autres
- Pango : il s'agit de la bibliothèque d'affichage et de rendue de textes.
- ATK.
La bibliothèque GTK+ en elle-même utilise une approche orientée objet et repose sur plusieurs couches :
- GObject : il s'agit de la base de l'implémentation des objets pour la POO ;
- GDK : bibliothèque graphique de bas niveau ;
- GTK+ : la bibliothèque GTK+ elle-même basée sur l'utilisation de widgets (1).
C'est bien sûr cette dernière qui nous intéresse ici, mais la glib nous sera aussi d'une grande aide.
I-C-3. Pourquoi utiliser GTK+ ?▲
Effectivement, pourquoi choisir d'utiliser GTK+ plutôt qu'une autre bibliothèque pour réaliser une interface graphique. Voici quelques arguments :
- GTK+ est sous licence libre LGPL, vous pouvez donc l'utiliser pour développer des programmes libres ou commerciaux ;
- la portabilité : GTK+ est disponible sur un grand nombre de systèmes dont Windows, Linux, Unix et MacOSX ;
- GTK+ est développée en C et pour le langage C, cependant elle est disponible pour d'autres langages tels que Ada, C++ (grâce à gtkmm), Java, Perl, PHP, Python, Ruby ou plus récemment C#.
I-D. Installation▲
I-D-1. Windows▲
Pour pouvoir exécuter une application utilisant GTK+, il faut commencer par installer les binaires. Pour faciliter leur installation, il existe un installeur :
Si vous utilisez the Gimp, utilisez les runtimes proposées sur le site https://www.gimp.org/downloads/devel/.
Pour développer une application, il faut les bibliothèques ainsi que les fichiers d'en-tête disponibles sur gtk.org. Pour ceux qui utilisent Code::Blocks, voici la méthode à suivre : Installation de Gtk+ sous Code::Blocks ?
I-D-2. Linux▲
Sous Linux, vous disposez sûrement d'un système de paquets. Il vous faudra installer deux paquets, le premier contenant les fichiers permettant d'exécuter des programmes utilisant GTK+, le second paquet contient les fichiers nécessaires au développement.
Une fois l'installation réussie, compilez à l'aide de la commande :
gcc -Werror -Wall -W -O2 -ansi -pedantic `pkg-config --cflags --libs gtk+-2.0`
*.c
Tous les codes de ce tutoriel ont été testés sous Linux Debian et Windows XP avec Code::Blocks.
I-E. La philosophie GTK+▲
Voici quelques choix qui ont été faits par l'équipe de développement de GTK+ :
- les noms de fonctions sont de la forme gtk_type_du_widget_action, ceci rend les noms des fonctions très explicites, en contrepartie ils peuvent être très longs ;
- tous les objets manipulés sont des GtkWidget, pour que GTK+ vérifie qu'il s'agit du bon type d'objet lors de l'appel à une fonction, chaque type de widget possède une macro de la forme GTK_TYPE_DU_WIDGET à utiliser pour transtyper vos widgets ;
- la gestion des événements qui modifient le comportement de l'application (clic de souris, pression d'une touche du clavier…) se fait grâce à l'utilisation de fonctions de rappel (callback). Pour cela, on connecte les widgets à des fonctions qui seront appelées lorsque l'événement survient.
I-F. Quelques notions de POO▲
La POO ou Programmation Orientée Objet est un mode de programmation basée sur des objets. GTK+ utilisant ce principe (2), je vais vous en expliquer les principes de base.
Plutôt que le déroulement du programme soit régi par une suite d'instruction, en POO il est régi par la création, l'interaction et la destruction d'objets, en résumé la vie des objets qui le composent. Un objet est une entité (le parallèle avec la vie courante est simple, un objet pourrait être un ordinateur), en C on pourrait se représenter un objet comme une structure de données.
Un objet est composé de propriétés (ce qui correspond à nos variables) et de méthodes (des fonctions). Pour créer un objet, on fait appel à son constructeur, il s'agit d'une fonction qui a pour but de créer et d'initialiser l'objet. À la fin de sa vie, l'objet doit être détruit, c'est le but du destructeur.
Dans la vie courante, on peut créer des objets complexes à partir de briques de base, il est possible de créer de nouveaux objets en se basant sur un ou plusieurs objets : ce mécanisme est appelé héritage (on parle d'héritage multiple lorsqu'il met en jeu plusieurs objets parents). L'objet ainsi obtenu hérite des propriétés et des méthodes de ses parents tout en pouvant modifier leur comportement et créer ses propres propriétés et méthodes.
Lorsque l'on souhaite créer un patron pour de futures classes, plutôt que de créer une classe de base qui ne sera jamais instanciée, il est possible de créer une interface.
Le dernier concept de POO qui va nous servir dans ce tutoriel est le polymorphisme. Ceci permet à un objet (prenons par exemple camion), de se comporter comme l'un de ses parents (dans le cas du camion, il peut être vu comme un véhicule, au même titre qu'une voiture). Ceci est aussi valable pour des classes implémentant la même interface.
Pour vous initier aux joies de la programmation orientée objet en C, je vous conseille le tutoriel de CGI : POO en C
I-G. Notre premier programme▲
Un programme qui utilise GTK+ est un programme écrit en C avant tout, il contient donc le code de base de tout programme C :
#include <stdlib.h>
int
main (
int
argc, char
**
argv)
{
/* ... */
return
EXIT_SUCCESS;
}
Pour pouvoir utiliser les fonctions de GTK+, il faut bien sûr inclure le fichier d'en-tête correspondant :
#include <gtk/gtk.h>
La première chose à faire est d'initialiser la machinerie GTK+ grâce à la fonction gtk_init :
void
gtk_init (
int
*
argc, char
***
argv);
Cette fonction reçoit les arguments passés en ligne de commande, ceux qui sont spécifiques à GTK+ sont ensuite retirés de la liste; d'où l'utilisation des pointeurs.
Ensuite, il nous faut créer tous les widgets dont nous avons besoin, si nécessaire modifier leurs paramètres par défaut, les connecter à des fonctions callback et ensuite demander leur affichage (tout ceci sera explicité dans la suite du tutoriel). Une fois la fenêtre principale créée, il suffit de lancer la boucle principale de GTK+ :
void
gtk_main (
void
);
Cette fonction est une boucle sans fin (seule la fonction gtk_main_quit permet d'en sortir) qui se charge de gérer le déroulement de notre programme (affichage des widgets, envoi de signaux…).
Voici donc notre premier programme en C/GTK+ qui ne fait rien :
#include <stdlib.h>
#include <gtk/gtk.h>
int
main (
int
argc, char
**
argv)
{
/* Initialisation de GTK+ */
gtk_init (&
argc, &
argv);
/* Creation de la fenetre principale de notre application */
/* Lancement de la boucle principale */
gtk_main
(
);
return
EXIT_SUCCESS;
}
En plus de ne rien faire, notre programme ne peut être terminé que de façon brutale (Ctrl+C) puisque nous n'appelons pas la fonction gtk_main_quit.