Date de publication : 20 Février 2007
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.
Nous allons maintenant voir comment créer un label, et comment l'insérer dans la fenêtre principale.
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!");
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 :
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);
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);
#include <stdlib.h> #include <gtk/gtk.h> int
main(int argc,char
**argv) gtk_init(&argc,&argv); pWindow = gtk_window_new(GTK_WINDOW_TOPLEVEL);
/* Creation du label */ /* On ajoute le label a
l'interieur de la fenetre */ /* Affichage de la fenetre
et de tout ce qu'il contient */ /* Connexion du signal gtk_main(); return EXIT_SUCCESS;
|
Résultat : |
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()
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.
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.
#include <stdlib.h> #include <gtk/gtk.h> int
main(int argc,char
**argv) gtk_init(&argc, &argv); pWindow = gtk_window_new(GTK_WINDOW_TOPLEVEL);
/* Creation du label avec
g_locale_to_utf8 */ /* On ajoute le label a
l'interieur de la fenetre */ /* Affichage de la fenetre
et de tout ce qu'il contient */ /* Connexion du signal gtk_main(); return EXIT_SUCCESS;
|
Résultat : |
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).
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.
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).
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>.
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 :
Au contraire, pour obtenir l'alignement du texte, la fonction est :
GtkJustification gtk_label_get_justify (GtkLabel *label);
#include <stdlib.h> #include <gtk/gtk.h> int
main(int argc,char
**argv) gtk_init(&argc,&argv); pWindow = gtk_window_new(GTK_WINDOW_TOPLEVEL);
/* Creation du label avec
g_locale_to_utf8 */ /* On utilise les balises
*/ /* On centre le texte
*/ /* On ajoute le label
a l'interieur de la fenetre */ /* Affichage de la fenetre
et de tout ce qu'il contient */ /* Connexion du signal gtk_main(); return EXIT_SUCCESS;
|
Résultat : |
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. |