Pour la suite des TP vous allez devoir choisir un IDE pour travailler. Vous avez le choix entre uniquement Eclipse (initié par IBM Corporation) et Visual Studio (de Microsoft Corporation) car ce sont les IDE les plus répandus en entreprise.
En ce qui nous concerne, la principale différence entre les deux sera qu'Eclipse fait appel à GCC pour compiler les programmes C, alors que Visual Studio utilise le compilateur interne de Microsoft.
Dans le présent TP nous allons voir que lorsqu'on travaille avec un IDE et que l'on doit utiliser une bibliothèque (comme GTK, mais c'est valable pour toute bibliothèque, comme OpenCV, OpenGL, …), il faut alors paramétrer l'environnement de compilation du projet (un peu comme le rôle joué par le fichier Makefile lors du TP1).
Après avoir créé un nouveau projet de nom MonProjet, ouvrir la fenêtre des propriétés du projet : Projet > Propriétés de Addition… ou +
Dans la section Propriétés de configuration > Répertoire VC++
Pour la propriété « Répertoires Include », ajouter en début de ligne et sans supprimer ce qui était déjà en place la ligne suivante : C:\Program Files (x86)\GTK\lib\glib-2.0\include;C:\Program Files (x86)\GTK\lib\gtk-2.0\include;C:\Program Files (x86)\GTK\include\atk-1.0;C:\Program Files (x86)\GTK\include\gdk-pixbuf-2.0;C:\Program Files (x86)\GTK\include\pango-1.0;C:\Program Files (x86)\GTK\include\cairo;C:\Program Files (x86)\GTK\include\glib-2.0;C:\Program Files (x86)\GTK\include\gtk-2.0;
Pour la propriété « Répertoires de bibliothèques », en début de ligne et sans supprimer ce qui était déjà en place la ligne suivante : C:\Program Files (x86)\GTK\bin;C:\Program Files (x86)\GTK\lib;
Dans la section Propriétés de configuration > Éditeurs de liens > Général
Pour la propriété « Répertoires de bibliothèques supplémentaires », en début de ligne et sans supprimer ce qui était déjà en place la ligne suivante : C:\Program Files (x86)\GTK\lib\gtk-2.0;C:\Program Files (x86)\GTK\lib;C:\Program Files (x86)\GTK\bin;
Dans la section Propriétés de configuration > Éditeurs de liens > entrée
Pour la propriété « Dépendances supplémentaires », en début de ligne et sans supprimer ce qui était déjà en place la ligne suivante : glib-2.0.lib;gio-2.0.lib;cairo.lib;atk-1.0.lib;gdk-win32-2.0.lib;gdk_pixbuf-2.0.lib;gthread-2.0.lib;gtk-win32-2.0.lib;libpng.lib;pango-1.0.lib;pangocairo-1.0.lib;pangowin32-1.0.lib;gmodule-2.0.lib;gailutil.lib;freetype.lib;fontconfig.lib;expat.lib;gobject-2.0.lib;
Ajoutez 3 nouveaux fichiers au projet en les nommant main.c, callbacks.c et callbacks.h (et bien en .c et non pas en .cpp sinon cela ne fonctionnera pas)
Dans la section C/C++ Build > Settings > GCC C Compiler > Miscellaneous
Dans la propriété « Other flags », ajouter l'option -mms-bitfields (en faisant attention le laisser un espace pour ne pas coller aux options déjà en place)
Un bouton compteur (Spin Button) de nom spinbutton_longueur
Vous allez connecter le signal "value-changed" avec :
La fonction on_hscale_longueur_value_changed() pour hscale_longueur
La fonction on_spinbutton_longueur_value_changed() pour spinbutton_longueur
Vous allez connecter le signal "realize" de la fenêtre window1 avec la fonction on_window1_realize(), et le signal "destroy" (de la fenêtre window1) avec la fonction on_window1_destroy()
Pensez à enregistrer votre fichier. Attention, pour la suite il devra se trouver dans le bon répertoire :
Avec Eclipse : le fichier mon_projet.glade doit se trouver dans le répertoire C:\PROG1ACI\ECLIPSE_C_WORKSPACE\MonProjet\ Figure 2.1.2
Avec Visual Studio : le fichier mon_projet.glade doit se trouver dans le répertoire C:\PROG1ACI\VISUALSTUDIO_WORKSPACE\MonProjet\MonProjet\ Figure 2.1.3
2.2 Dans le fichier main.c
De retour dans votre IDE, vous allez écrire le code du fichier main.c. Reprenez la fonction main() déjà faite au TP1 et prenez soin de spécifier le nom du fichier mon_projet.glade lors de la construction de l'interface avec le builder de GTK.
2.3 Dans le fichier callbacks.h
Dans le fichier callbacks.h vous allez déclarer les prototypes des quatre fonctions suivantes en prenant soin de respecter le prototype des fonctions de rappels (se référer au TP1) :
on_window1_realize()
on_window1_destroy()
on_hscale_longueur_value_changed()
on_spinbutton_longueur_value_changed()
2.4 Dans le fichier callbacks.c
Les curseurs horizontaux et les boutons compteurs, qui servent à spécifier un nombre par l'utilisateur, sont caractérisés par :
La valeur minimum qu'il est possible de prendre
La valeur maximum qu'il est possible de prendre
La valeur courante
Une valeur d'incrément
Le nombre de chiffres après la virgule
Ajoutez les deux fonctions suivantes qui serviront plus tard à initialiser des boutons compteurs et des curseurs horizontaux : Code 2.4.1
La fonction on_window1_realize() sera appelée lors de la création de la fenêtre, une fois que tous les widgets ont fini d'être créés. C'est dans cette fonction que nous allons configurer les valeurs initiales du curseur horizontal et du bouton compteur. Les valeurs à donner sont :
Valeur minimum : 0.0
Valeur maximum : 10000.0
Valeur initiale : 100.0
Incrément : 0.1
Décimales : 1
Si besoin, voir dans le TP1 comment récupérer un pointeur vers un composant de l'interface (au travers de la variable globale builder …), comme cela avait été fait dans la fonction on_button_addition_clicked().
La fonction on_window1_destroy() sera appelée lors de la fermeture de la fenêtre. Cette fonction appellera la fonction d'arrêt gtk_main_quit(); de la boucle GTK (comme fait dans le TP1).
La fonction on_hscale_longueur_value_changed() sera appelée lorsque la valeur du curseur horizontal a été modifiée (par l'utilisateur ou par le programme). Cette fonction va simplement récupérer la valeur du curseur horizontal et l'attribuer au bouton compteur, de sorte que ces deux composants posséderont ainsi la même valeur.
La fonction gtk_range_get_value() permet de récupérer la valeur courante d'un curseur
La fonction on_spinbutton_longueur_value_changed() sera appelée lorsque la valeur du bouton compteur a été modifiée (par l'utilisateur ou par le programme). Cette fonction va simplement récupérer la valeur du bouton compteur et l'attribuer au curseur horizontal, de sorte que ces deux composants posséderont ainsi toujours la même valeur.
La fonction gtk_range_set_value() permet de modifier la valeur courante d'un curseur
2.5 Compilation et test
Vous avez commencé par configurer votre projet pour pouvoir utiliser la bibliothèque GTK, puis vous venez d'écrire un petit programme. Assurez-vous maintenant que tout fonctionne bien.
Comme au TP1, si jamais un message d'erreur apparaît concernant les DLL (p. ex. : zlib1.dll), c'est parce que d'autres versions de la bibliothèque sont installées sur votre système. Dans ce cas, copiez directement la bonne version des DLL de GTK à côté de votre exécutable, comme ceci :
Pour Eclipse : copy C:\"Program Files (x86)"\GTK\bin\*.dll C:\PROG1ACI\ECLIPSE_C_WORKSPACE\MonProjet\Debug\
Pour Visual Studio : copy C:\"Program Files (x86)"\GTK\bin\*.dll C:\PROG1ACI\VISUALSTUDIO_WORKSPACE\MonProjet\Debug\
Si la fenêtre est trop petite à l'exécution (a) vous pouvez la redimensionner avec votre souris (b) afin de pouvoir tester votre curseur horizontal. Il est possible d'améliorer un peu ce comportement en spécifiant dans Glade la valeur oui pour la propriété "homogène" des boîtes horizontales. Le curseur horizontal et le bouton compteur occuperont alors un espace de taille identique (c). Il est possible d'améliorer encore, mais pour le moment il ne faut pas trop se préoccuper de genre de soucis de dimension des composants qui disparaîtront en partie lorsque l'interface sera plus complète.
Figure 2.5.1
Si jamais vous n'avez pas sélectionné le bon compilateur lors de la création du projet (p. ex. : Cross GCC), vous pouvez rectifier en faisant comme suit : → Dans la fenêtre des propriétés du projet → Dans la section C/C++ Build > Tool Chain Editor →Modifier la propriété « Current toolchain » et choisir « MinGW GCC »
2.6 Une fonction de mise à jour
Ajoutez une étiquette (un label) de nom label_longueur dans votre interface.
Créez dans callbacks.c une nouvelle fonction rafraichir_affichage() comme suit :
Le prototype exact de la fonction (qui n'est pas une fonction de rappel) sera : void rafraichir_affichage () ;
Cette fonction récupérera la valeur courante du bouton compteur et modifiera le texte de l'étiquette en affichant la valeur de la longueur. Si besoin, voir dans le TP1 comment modifier le texte d'une étiquette à l'aide de la fonction sprintf().
Ajoutez un appel à la fonction rafraichir_affichage() dans la fonction on_spinbutton_longueur_value_changed() (et seulement ici, pas dans on_hscale_longueur_value_changed() car il n'est pas nécessaire de rafraîchir deux fois l'étiquette avec la même valeur).
Avec le compilateur VC (sous Visual Studio), au lieu de sprintf(), vous utiliserez sprintf_s() en indiquant la taille du buffer en deuxième argument. Par exemple : char msg[128] = "" ; sprintf_s(msg, 128, "la_chaine_a_ecrire") ;
Modifier la fonction rafraichir_affichage() de sorte que l'étiquette label_message affiche :
"Moins de 5000" en gras vert, si la valeur de la longueur est inférieure à 5000
"Plus de 5000" en gras rouge, si la valeur de la longueur est supérieure à 5000
Figure 3.2
Une fois que l'option « Utiliser des balises » est activée, c'est désormais la fonction gtk_label_set_markup() qui doit être utilisée pour modifier le texte d'une étiquette.
Pour mettre du texte en gras, il faut entourer ce texte par deux balises <b>le texte</b>
Pour changer la couleur du texte, il faut entourer ce texte par deux balises <span foreground=\"#000000\">le texte</span> où #000000 sera un code couleur HTML.