
Introduction `aGTK Fr´ed´eric Devernay [email protected] 8 novembre 1999 R´esum´e Nous verrons d'abord l'organisation g´en´erale de GTK et de GNOME. Nous d´etaillerons ensuite l'utilisation de la biblio- th`eque de portabilit´e GLib, puis quelques exemples d'utilisa- tion de GTK. Pourquoi GNOME et GTK? { Parce que GTK ne d´epend pas du langage utilis´e (= Qt), 6 est portable et extensible, et que le source est disponible. { Parce que GNOME est bas´e sur des concepts largement r´epandus dans l'industrie (CORBA, XML), mais peu en- seign´es. { Et en plus c'est beau ! (th`emes, etc.) L'architecture logicielle de GTK/GNOME La hi´erarchie des biblioth`equesde GNOME { Les biblioth`eques GNOME sont haut niveau (notion d'applica- tion, fichiers de config...) { GTK+ est compos´e de GTK (widget toolkit) et GDK (primitives de dessin bas niveau) { GLib est une biblioth`eque de portabilit´e (types, fonctions stan- dard) et d'utilitaires (listes, tables de hachage, ...) 1 Les biblioth`equesGNOME { libgnome : utilitaires ind´ependants de la toolkit ; { libgnomeui : ... dependants de la toolkit (combos, ...) ; { libgnorba : utilisation de corba, via ORBit ; { gtk-xmhtml : widget HTML pour GTK ; { xvt : widget d'´emulation de terminal ; { libvfs : file syst`eme virtuel utilis´e dans Midnight Commander ; { libart lgpl : biblioth`eque graphique avec anti-aliasing. Mais commen¸cons par le d´ebut : GLib, puis GTK, puis GNOME. Caract´eristique commune de toutes ces biblioth`eques : peu de documentation. Resources disponibles : www.gtk.org (GTK) • developer.gnome.org/doc (GNOME) • www-mips.unice.fr/ devernay/cours/IHM (le site du cours) • { les includes de GTK, GLib, ... 2 GLib Les noms de fonction commencent par g (g strdup), les types par g (gint32), les structures sont capitalis´ees et commencent par G (GHashTable). Typedefs : { gint8 : entier sign´e8 bits { guint8 : entier non sign´e8 bits { ... gint16, guint16, gint32, guint32, gint64 et guint64 (dispo si G HAVE GINT64 est d´efini), gchar, guchar, gshort, gushort, glong, gulong, gint, guint, gfloat, gdouble, gboolean (en fait un int, prend les valeurs TRUE ou FALSE), gpointer (= void *), gconstpoin- ter (= const void *) Portabilit´eet Utilitaires : { gchar* g strdup (const gchar*) = stdup() { g malloc, g free { void g usleep (gulong count) suspend l'ex´ecutionpendant 'count' microsecondes { g snprintf = snprintf `autiliser pour raisons ´eviterles ’buffer over- flows' (s´ecurit´e++) { g new(type,count) (= (type) g malloc(count*sizeof(type))), g new0 id. mais met `az´ero { gchar* g strconcat (const gchar *str, ..., NULL) concat`eneles cha^ınesen param`etres(alloue une nouvelle cha^ıne) { g strdup printf comme un sprintf, mais alloue la cha^ıne { g strstrip coupe les espaces au d´ebutet `ala fin d'une cha^ıne, n'alloue pas, ne d´esallouepas 3 GLib : Les containers { GList : liste doublement cha^ın´ee { GSList : liste simplement cha^ın´ee { GHashTable : table de hachage { GCache : cache { GTree : arbre binaire ´equilibr´e { GNode : arbre n-aire { GString : cha^ınede caract`eresde taille dynamique { GArray : tableau de taille dynamique { GPtrArray : tableau de pointeurs de taille dynamique { GByteArray : tableau d'octets (guint8) de taille dynamique Listes { GList* g list append (GList *list, gpointer data) ajoute data `alist. list peut ^etreNULL (cr´eation) { g list prepend, g list remove, g list find, g list next, g list previous, g list free (ne lib`erepas les data !) Cha^ınesde caract`eres /* le char* est dans le champ str de GString. */ GString* g_string_new (const gchar *init); void g_string_free (GString *string, gint free_segment); GString* g_string_append (GString *string, const gchar *val); GString* g_string_prepend (GString *string, const gchar *val); void g_string_sprintf (GString *string, const gchar *format, ...) G_GNUC_PRINTF (2, 3); void g_string_sprintfa (GString *string, const gchar *format, ...) G_GNUC_PRINTF (2, 3); etc... Autres containers (/usr/include/glib.h), constantes et macros de conver- sion portables... m^emesous MSWindows (/usr/lib/glib/include/glibconfig.h). 4 GTK : introduction { Il existe des interfaces C++ (GTK{), python (pyGTK), perl (perlGTK), ..., mais nous allons utiliser l'interface C (les autres lui ressemblent). { GTK+ est ´ecrit en C orient´e-objet : impl´emente les notions de classe, d'h´eritage (simple), de m´ethodes virtuelles, de typage fort (`a l'ex´ecution) et de fonctions de rappel (callbacks). Premier exemple : affiche une fen^etre 200x200 #include <gtk/gtk.h> int main (int argc, char *argv[]) { GtkWidget *window; /* recherche sur la ligne de commande les arguments --gtk-module --g-fatal-warnings --display --sync --no-xshm --name --class */ gtk_init (&argc, &argv); /* cr´eeune fen^etreet l'affiche */ window = gtk_window_new (GTK_WINDOW_TOPLEVEL); gtk_widget_show (window); /* boucle d’´ev`enements*/ gtk_main (); return 0; } 5 GTK : Bonjour tout le monde #include <gtk/gtk.h> /* fonction de rappel. Dans cet exemple, les param`etressont ignor´es... * Les fonctions de rappel sont d´etaill´eesplus loin. */ void hello (GtkWidget *widget, gpointer data) { g_print ("Bonjour tout le monde.\n"); } gint delete_event(GtkWidget *widget, GdkEvent *event, gpointer data) { g_print ("le signal delete_event est survenu.\n"); /* Si l'on renvoit TRUE dans le gestionnaire du signal "delete_event", * GTK ´emettrale signal "destroy". Retourner FALSE signifie que l'on * ne veut pas que la fen^etresoit d´etruite. * Utilis´epour faire appara^ıtredes bo^ıtesde dialogue du type * (( Etes-vous^ s^urde vouloir quitter ? )) */ /* Remplacez FALSE par TRUE et la fen^etreprincipale sera d´etruitepar * un signal (( delete_event )). */ return (FALSE); } /* Autre fonction de rappel */ void destroy (GtkWidget *widget, gpointer data) { gtk_main_quit (); } int main (int argc, char *argv[]) { 6 /* GtkWidget est le type pour d´eclarerles widgets. */ GtkWidget *window; GtkWidget *button; /* Cette fonction est appel´eedans toutes les applications GTK. * Les param`etrespass´esen ligne de commande sont analys´eset * retourn´es`al'application. */ gtk_init (&argc, &argv); /* Cr´eationd'une nouvelle fen^etre.*/ window = gtk_window_new (GTK_WINDOW_TOPLEVEL); /* Lorsque la fen^etrere¸coitle signal "delete_event" * (envoy´epar le gestionnaire de fen^etresen utilisant l'option * (( close )) ou la barre de titre), on lui demande d'appeler la * fonction delete_event() d´efinieplus haut. La donn´eepass´eeen * param`etre`ala fonction de rappel est NULL et est ignor´edans le * rappel. */ gtk_signal_connect (GTK_OBJECT (window), "delete_event", GTK_SIGNAL_FUNC (delete_event), NULL); /* Ici, on connecte l’´evenement"destroy" `aun gestionnaire de signal. * Cet ´ev´enementarrive lorsqu'on appelle gtk_widget_destroy() sur la * fen^etre,ou si l'on retourne TRUE dans le rappel "delete_event". */ gtk_signal_connect (GTK_OBJECT (window), "destroy", GTK_SIGNAL_FUNC (destroy), NULL); /* Configuration de la largeur du contour de la fen^etre.*/ gtk_container_border_width (GTK_CONTAINER (window), 10); /* Cr´eationd'un nouveau bouton portant le label * "Bonjour tout le monde". */ button = gtk_button_new_with_label ("Bonjour tout le monde"); /* Quand le bouton recevra le signal "clicked", il appellera la 7 * fonction hello() d´efinieplus haut en lui passant NULL en param`etre.*/ gtk_signal_connect (GTK_OBJECT (button), "clicked", GTK_SIGNAL_FUNC (hello), NULL); /* Ceci provoquera la destruction de la fen^etrepar appel de la * fonction gtk_widget_destroy(window) lors du signal "clicked". * Le signal de destruction pourrait venir de l`a,ou du * gestionnaire de fen^etres.*/ gtk_signal_connect_object (GTK_OBJECT (button), "clicked", GTK_SIGNAL_FUNC (gtk_widget_destroy), GTK_OBJECT (window)); /* Insertion du bouton dans la fen^etre(container gtk). */ gtk_container_add (GTK_CONTAINER (window), button); /* L’´etapefinale consiste `aafficher ce nouveau widget... */ gtk_widget_show (button); /* ... et la fen^etre.*/ gtk_widget_show (window); /* Toutes les applications GTK doivent avoir un gtk_main(). * Le d´eroulementdu programme se termine l`aet attend qu'un * ´ev´enementsurvienne (touche press´eeou ´ev´enementsouris). */ gtk_main (); return 0; } Compilation gcc -Wall -g -I/usr/lib/glib/include bonjour.c -o bonjour_monde \ -L/usr/X11R6/lib -lgtk -lgdk -lglib -lXext -lX11 -lm ou gcc bonjour.c -o bonjour_monde `gtk-config --cflags --libs` 8 GTK : th´eorie des signaux et rappels GTK est dirig´e par les ´ev´enements : il reste dans gtk main() jusqu'`a ce qu'un ´ev´enement arrive (ex. bouton). Il faut connecter le gestionnaire de signaux sur la fonction de rappel : /* retourne un identificateur de la fonction de rappel */ gint gtk_signal_connect( GtkObject *object, /* widget ´emet- teur */ gchar *name, /* nom du signal */ GtkSignalFunc func, /* fctn de rap- pel */ gpointer func_data ); /* donn´ees*/ /* d´econnectele signal */ void gtk_signal_disconnect( GtkObject *object, gint id ); /* d´econnectetous les signaux */ void gtk_signal_handlers_destroy( GtkObject *object ); La fonction de rappel a (en g´en´eral) la forme : void callback_func( GtkWidget *widget, /* widget ´emetteur*/ gpointer callback_data ); /* donn´ees*/ Autre forme (utile pour appeler une fctn GTK prenant un objet) : gint gtk_signal_connect_object( GtkObject *object, gchar *name, GtkSignalFunc func, GtkObject *slot_object ); void callback_func( GtkObject *object ); 9 GTK : ´ev´enements event, button press event, button release event, motion notify event, delete event, destroy event, expose event, key press event, key release event, enter notify event, leave notify
Details
-
File Typepdf
-
Upload Time-
-
Content LanguagesEnglish
-
Upload UserAnonymous/Not logged-in
-
File Pages49 Page
-
File Size-