Les labels
Maintenant que nous savons créer une fenêtre, nous allons créer
l'incontournable "Hello World!". Pour cela, nous allons utiliser le
widget GtkLabel qui nous permet d'afficher du texte.

1. Création et affichage d'un label.
Nous allons maintenant voir comment créer un label, et comment l'insérer
dans la fenêtre principale.
1.1 Création d'un label.
On crée un pointeur vers la structure GtkWidget.
Dans un premier temps, il faut déclarer le pointeur sur l'objet GtkLabel
:
GtkWidget *pLabel;
Ensuite il faut initialiser cet objet. Pour cela, il n'existe qu'une seule
fonction :
GtkWidget* gtk_label_new(const char* str);
Le paramètre str n'est autre que la chaîne
de caractères qu'il faudra afficher.
Pour notre exemple, la ligne de code sera :
pLabel = gtk_label_new("Hello World!");
1.2 Insérer le texte dans la fenêtre.
Pour pouvoir afficher le texte, il faut insérer le widget pLabel
dans la fenêtre principale (widget pWindow). Pour cela, nous
allons utiliser le fait que le widget GtkWindow dérive du widget GtkContainer.
L'atout principal d'un GtkContainer est, comme son nom le laisse entendre, qu'il
peut contenir et afficher un autre widget. Les widgets de ce type sont appelés
des conteneurs. Il faudra donc différencier deux types d'objets :
- le widget conteneur (aussi appelé widget parent) ;
- le widget contenu (aussi appelé widget enfant) qui pourra par la
suite devenir lui-même un conteneur s'il possède les propriétés
de GtkContainer.
Etudions donc maintenant la fonction qui nous servira à insérer
un widget dans un widget conteneur :
void gtk_container_add(GtkContainer *container, GtkWidget
*widget);
Le premier paramètre, container, est le widget conteneur
dans lequel on veut insérer le widget widget qui lui est
passé en deuxième paramètre. Le premier paramètre
de cette fonction est de type GtkContainer, alors que les widgets conteneurs
seront tous de type GtkWidget. Il faudra donc à nouveau utiliser une
macro de conversion qui cette fois est GTK_CONTAINER().
Pour notre exemple, la ligne de code sera :
gtk_container_add(GTK_CONTAINER(pWindow), pLabel);
1.3 Afficher la fenêtre complète
Dans le chapitre précédent, nous avons utilisé la fonction
gtk_widget_show pour afficher la fenêtre. Mais cette fonction
n'affiche que la fenêtre et pas son contenu. Pour régler ce problème,
il est tout à fait possible d'utiliser deux fois cette fonction (une
première fois pour la fenêtre et deuxième fois pour le label).
Mais cette solution peut s'avérer très lourde s'il y a beaucoup
de widget à afficher.
La deuxième solution existante consiste à appeler cette fonction
:
void gtk_widget_show_all(GtkWidget *widget);
Cette fonction affiche, bien sur, le widget widget mais aussi tous les widgets
enfants qu'il inclut. Notre ligne de code sera donc :
gtk_widget_show_all(pWindow);
1.4 Programme exemple
#include <stdlib.h>
#include <gtk/gtk.h> int
main(int argc,char
**argv)
{
GtkWidget* pWindow;
GtkWidget* pLabel;
gtk_init(&argc,&argv);
pWindow = gtk_window_new(GTK_WINDOW_TOPLEVEL);
gtk_window_set_title(GTK_WINDOW(pWindow), "Les
labels");
gtk_window_set_default_size(GTK_WINDOW(pWindow),
320, 200);
/* Creation du label */
pLabel=gtk_label_new("Hello World!");
/* On ajoute le label a
l'interieur de la fenetre */
gtk_container_add(GTK_CONTAINER(pWindow), pLabel);
/* Affichage de la fenetre
et de tout ce qu'il contient */
gtk_widget_show_all(pWindow);
/* Connexion du signal
/* On appelle directement la fonction de sortie
de boucle */
g_signal_connect(G_OBJECT(pWindow), "destroy",
G_CALLBACK(gtk_main_quit), NULL);
gtk_main();
return EXIT_SUCCESS;
} |
Résultat :
|
2. Les caractères accentués
Vous avez peut-être déjà essayé d'afficher du texte contenant des caractères tel
que "é, è, à, …", et lors de l'exécution, votre texte ne s'affiche complètement.
Nous allons maintenant voir le pourquoi du comment.
2.1 Application test
Pour vous montrer tout cela, nous allons reprendre l'exemple précédent en remplaçant
" Hello Word " par " Texte à afficher ", et cela ne marche pas! En effet vous
obtenez cela :
Et en plus sur la console, vous avez le message d'erreur suivant :
** (Label2.exe) : WARNING **: Invalid UTF8 string passed to pango_layout_set_text()
2.2 Comment ça marche ?
Pour afficher du texte, Gtk utilise la librairie Pango qui s'occupe du rendu
et de l'affichage du texte. Le but de Pango est de permettre l'internationalisation
des applications, et pour cela Pango utilise l'encodage UTF8. Ce charset est
codée sur 16 bits, ce qui offre la possibilité d'afficher plus
65000 caractères, permettant ainsi d'afficher des caractères accentués
et bien plus (ex : pour le grec, le chinois, ...).
Puisque Pango sait faire tout cela, pourquoi le test n'a-t-il pas fonctionné?
Et bien, tout simplement parce que votre système d'exploitation n'utilise
pas ce charset. Lorsque vous souhaitez afficher "Texte à afficher",
Pango va avant tout vérifier l'encodage d'un caractère et si l'un
de ces caractères n'est pas correct, Pango va arrêter son processus
de rendu et envoyer un message d'erreur.
Le moyen le plus simple pour voir les effets d'une erreur d'encodage est de
changer celui de votre navigateur. Modifiez les options de votre navigateur
afin d'utiliser l'encodage UNICODE. Cette page web utilisant le charset
iso-8859-1, les caractères accentués deviendront des carrés
ou autre chose.
2.3 Solution
Une seule chose s'impose à nous : il faut convertir notre chaîne de caractère
en UTF8. Pour cela, il faut utiliser une fonction de Glib qui est :
gchar* g_locale_to_utf8(const gchar *opsysstring, gsize len,
gsize *bytes_read, gsize *bytes_written, GError **error);
La valeur de retour est le pointeur sur la chaîne de caractère
fraîchement convertie. Si une erreur est survenue lors de la conversion,
g_locale_to_utf8 renvoie NULL. Il faudra tout de même libérer le
mémoire allouée par cette fonction lorsque la variable ne sera
plus utile.
Le premier paramètre opsysstring est la chaîne de
caractère à convertir et le second paramètre len
correspond à la longueur de la chaîne. Ce paramètre sera
en général égal à -1 (on laisse la bibliothèque
calculer la longueur toute seule).
Les trois derniers paramètres sont utiles en cas d'erreur lors de la
conversion. Tout d'abord bytes_read est le nombre d'octet qui ont
été lus dans le texte à convertir, et bytes_writen
le nombre d'octet qui ont été écris dans la nouvelle chaîne
de caractères.
Le dernier paramètre error, donne plus de précision
en cas d'erreur. Voici la liste des messages d'erreur possibles :
G_CONVERT_ERROR_NO_CONVERSION ;
G_CONVERT_ERROR_ILLEGAL_SEQUENCE ;
G_CONVERT_ERROR_FAILED ;
G_CONVERT_ERROR_PARTIAL_INPUT ;
G_CONVERT_ERROR_BAD_URI ;
G_CONVERT_ERROR_NOT_ABSOLUTE_PATH.
Pour notre exemple, nous n'allons pas utiliser les trois derniers paramètres.
En cas d'erreur, il n'y aura donc aucun moyen d'avoir plus de précision
sur l'erreur survenue.
2.4 Programme exemple
#include <stdlib.h>
#include <gtk/gtk.h> int
main(int argc,char
**argv)
{
GtkWidget* pWindow;
GtkWidget* pLabel;
gchar* sUtf8;
gtk_init(&argc, &argv);
pWindow = gtk_window_new(GTK_WINDOW_TOPLEVEL);
gtk_window_set_title(GTK_WINDOW(pWindow), "Les
labels II");
gtk_window_set_default_size(GTK_WINDOW(pWindow),
320, 200);
/* Creation du label avec
g_locale_to_utf8 */
sUtf8 = g_locale_to_utf8("Texte à
afficher", -1, NULL, NULL, NULL);
pLabel=gtk_label_new(sUtf8);
g_free(sUtf8);
/* On ajoute le label a
l'interieur de la fenetre */
gtk_container_add(GTK_CONTAINER(pWindow), pLabel);
/* Affichage de la fenetre
et de tout ce qu'il contient */
gtk_widget_show_all(pWindow);
/* Connexion du signal
/* On appelle directement la fonction de sortie
de boucle */
g_signal_connect(G_OBJECT(pWindow), "destroy",
G_CALLBACK(gtk_main_quit), NULL);
gtk_main();
return EXIT_SUCCESS;
} |
Résultat :
|
3. Formatage du texte
Nous allons maintenant voir comment modifier l'apparence de notre texte (police,
couleur, …).
Pour notre application test, nous allons afficher une ligne en Courier gras
taille 10, une ligne en Times New Roman italique bleu taille 12, et une ligne
en Verdana souligné taille 16. Et tout cela centré (bien sûr).
3.1 Définition du format
Une fois encore, nous allons utiliser les propriétés de Pango (même si nous
n'allons pas utiliser les fonctions de Pango directement).
Pour définir le format du texte, il suffit d'insérer des balises à l'intérieur
même de notre texte. Pango s'occupe ensuite de rechercher les balises puis de
formater le texte à notre convenance.
3.2 Les balises rapides
Les balises rapides servent à mettre le texte en gras, italique ou autre de
manière très simple. Voici l'intégralité de ces balises :
| Balise |
Action |
Exemple |
| <b> |
Met le texte en gras |
 |
| <big> |
Augment légèrement la taille du texte |
 |
| <i> |
Met le texte en italique |
 |
| <s> |
Barre le texte |
 |
| <sub> |
Met le texte en indice |
 |
<sup> |
Met le texte en exposant |
 |
| <small> |
Diminue légèrement la taille du texte |
 |
<tt> |
Met le texte en télétype |
 |
| <u> |
Souligne le texte |
 |
Pour utiliser ces balises, il suffit d'encadrer le texte à modifier
des balises de formatage. Par exemple, pour mettre le texte en gras, il faudra
entrer : "Normal vs <b>Gras</b>".
Mais cela ne suffit pas, il faut aussi dire que le texte utilise les balises
Pango, ce qui est possible avec la fonction suivante :
void gtk_label_set_use_markup(GtkLabel *label, gboolean setting);
Il faut mettre le paramètre setting à TRUE,
et le texte sera alors formaté en conséquence.
Un autre moyen de spécifier l'utilisation des balises, est d'utiliser
cette fonction :
void gtk_label_set_markup(GtkLabel *label, const gchar *str);
Cette fonction dit à Pango qu'il faut utiliser les balises, mais elle
modifie aussi le label en affichant la chaîne de caractères str
(deuxième paramètre).
3.3 La balise <span>
Cette fois-ci, nous allons étudier la balise <span> en détail.
Avec celle-ci, nous allons pouvoir changer la police de caractères, la
couleur du texte et bien d'autres choses.
Cette balise s'utilise comme les précédentes si ce n'est qu'elle
accepte des paramètres. Le tableau ci-dessous présente tous les
paramètres et les effets sur le texte.
| Paramètre |
Utilisation |
Exemple |
font_family |
Pour définir la police à utiliser. Si la valeur
donnée à ce paramètre est incorrecte, la police par
défaut (Sans Serif) sera utilisée.
Exemple : <span font_family=\"Courier New\">Courier
New</span> |
 |
face |
Identique à font_family
Exemple : <span face=\"Times New Roman\">Times New
Roman</span> |
 |
| size |
Pour définir la taille du texte (par défaut
10).
Exemple : <span size=\"12\">Taille 12</span> |
 |
| style |
Pour définir le style du texte. Trois valeurs possibles
: normal, oblique, italic.
Exemple : <span style=\"oblique\">Oblique</span> |
 |
| font_desc |
Permet de combiner les paramètres précédents
en un seul.
Exemple : <span font_desc=\"Courier New italic 12\">Courier
New italic 12</span> |
 |
| weight |
Permet de définir l'épaisseur des lettres.
Les valeurs peuvent être ultralight, light, normal, bold, utrabold,
heavy ou encore une valeur numérique. (Vous remarquerez qu'il n'y
a que peu ou pas de différence).
Exemple : <span weight=\"bold\">Bold</span> |
 |
| variant |
Pour définir si l'on veut du texte normal (normal)
ou en petite majuscule (smallcaps).
Exemple : <span variant=\"smallcaps\">Smallcaps</span>
Afin de pourvoir l'utiliser, il faut avoir la police : nom smallcaps |
|
| stretch |
Permet d'étirer le texte. La valeur de ce paramètre
peut être :
ultracondensed, extracondensed, condensed, semicondensed, normal, semiexpanded,
expanded, extraexpanded, ultraexpanded.
Afin de pourvoir l'utiliser, il faut avoir la police : nom condensed
(ou autre). |
|
| foreground |
Pour définir la couleur du texte. Il faut donner
la valeur hexadécimale de la palette RVB.
Exemple : <span foreground=\"#FF0000\">Couleur Texte</span> |
 |
| background |
Pour définir la couleur du fond. Il faut donner la
valeur hexadécimale de la palette RVB.
Exemple : <span background=\"#FF0000\">Couleur Texte</span> |
 |
| underline |
Pour souligner le texte.
Exemple : <span underline=\"double\">Double</span> |
 |
| rise |
Pour déplacer le texte verticalement. |
|
| strikethrough |
Pour barrer le texte.
Exemple : <span strikethrough=\"true\">Striketrough
= "true"</span> |
 |
| lang |
Pour indiquer la langue du texte. |
|
Tous ces paramètres peuvent être mis à l'intérieur
d'une seule balise <span>.
3.4 Alignement du texte
Maintenant, nous allons voir comment aligner notre texte, lorsque celui-ci
comporte plusieurs lignes. Comme d'habitude, GTK+ nous fourni une fonction très
simple d'utilisation :
void gtk_label_set_justify (GtkLabel *label, GtkJustification
jtype);
Le paramètre jtype correspond à l'alignement du texte et peut
prendre une de ces valeurs :
- GTK_JUSTIFY_LEFT pour aligner le texte à gauche (par défaut)
;
- GTK_JUSTIFY_RIGHT pour aligner le texte à droite ;
- GTK_JUSTIFY_CENTER pour centrer le texte ;
- GTK_JUSTIFY_FILL pour justifier le texte.
Au contraire, pour obtenir l'alignement du texte, la fonction est :
GtkJustification gtk_label_get_justify (GtkLabel *label);
3.5 Programme exemple.
#include <stdlib.h>
#include <gtk/gtk.h> int
main(int argc,char
**argv)
{
GtkWidget* pWindow;
GtkWidget* pLabel;
gchar* sUtf8;
gtk_init(&argc,&argv);
pWindow = gtk_window_new(GTK_WINDOW_TOPLEVEL);
gtk_window_set_title(GTK_WINDOW(pWindow),"Les
labels III");
gtk_window_set_default_size(GTK_WINDOW(pWindow),320,200);
/* Creation du label avec
g_locale_to_utf8 */
pLabel=gtk_label_new(NULL);
/* On utilise les balises
*/
sUtf8 = g_locale_to_utf8("<span face=\"Courier
New\"><b>Courier New 10 Gras</b></span>\n"
"<span font_desc=\"Times
New Roman italic 12\" foreground=\"#0000FF\">Times New
Roman 12 Italique</span>\n"
"<span face=\"Sans\"
size=\"16\"><u>Sans 16 Souligné</u></span>",
-1, NULL, NULL, NULL);
gtk_label_set_markup(GTK_LABEL(pLabel), sUtf8);
g_free(sUtf8);
/* On centre le texte
*/
gtk_label_set_justify(GTK_LABEL(pLabel), GTK_JUSTIFY_CENTER);
/* On ajoute le label
a l'interieur de la fenetre */
gtk_container_add(GTK_CONTAINER(pWindow),pLabel);
/* Affichage de la fenetre
et de tout ce qu'il contient */
gtk_widget_show_all(pWindow);
/* Connexion du signal
/* On appelle directement la fonction de sortie
de boucle */
g_signal_connect(G_OBJECT(pWindow),"destroy",G_CALLBACK(gtk_main_quit),0);
gtk_main();
return EXIT_SUCCESS;
} |
| Résultat :

|
4. En savoir plus :
4.1 Fonctions documentées
void gtk_label_set_text (GtkLabel* label, const char*
str)
void gtk_label_set_label(GtkLabel* label, const gchar* str) |
Ces deux fonctions permettent de changer le texte d'un
GtkLabel. Entrée(s) : label : objet
GtkLabel. str : nouveau texte. Sortie :
rien. |
G_CONST_RETURN gchar* gtk_label_get_text(GtkLabel* label)
G_CONST_RETURN gchar* gtk_label_get_label(GtkLabel* label) |
Permet de recevoir l'adresse de la chaîne de caractère
affichée par le label.
Entrée(s) :
label : objet GtkLabel. Sortie : const
gchar*. |
| gboolean gtk_label_get_use_markup (GtkLabel *label); |
Permet de savoir si un label utilise les balises de formatages
Pango.
Entrée(s) :
label : objet GtkLabel. Sortie : gboolean, si oui
TRUE, sinon FALSE. |
4.2 Fonctions non documentées
void gtk_label_set_attributes (GtkLabel *label, PangoAttrList *attrs);
void gtk_label_set_markup_with_mnemonic(GtkLabel *label, const gchar *str);
void gtk_label_set_pattern (GtkLabel *label, const gchar *pattern);
guint gtk_label_parse_uline (GtkLabel *label, const gchar *string);
void gtk_label_set_line_wrap (GtkLabel *label, gboolean wrap);
void gtk_label_get_layout_offsets (GtkLabel *label, gint *x, gint *y);
guint gtk_label_get_mnemonic_keyval (GtkLabel *label);
gboolean gtk_label_get_selectable (GtkLabel *label);
GtkWidget* gtk_label_new_with_mnemonic (const char *str);
void gtk_label_select_region (GtkLabel *label, gint start_offset, gint end_offset);
void gtk_label_set_mnemonic_widget (GtkLabel *label, GtkWidget *widget);
void gtk_label_set_selectable (GtkLabel *label, gboolean setting);
void gtk_label_set_text_with_mnemonic(GtkLabel *label, const gchar *str);
PangoAttrList* gtk_label_get_attributes (GtkLabel *label);
PangoLayout* gtk_label_get_layout (GtkLabel *label);
gboolean gtk_label_get_line_wrap (GtkLabel *label);
GtkWidget* gtk_label_get_mnemonic_widget (GtkLabel *label);
gboolean gtk_label_get_selection_bounds (GtkLabel *label, gint *start, gint *end);
gboolean gtk_label_get_use_underline (GtkLabel *label);
void gtk_label_set_use_underline (GtkLabel *label, gboolean setting);
Date de mise à jour : 17 mai 2003