IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)

Cours GTK 2

Date de publication : 20 Février 2007



La barre d'état

La barre d'état peut avoir plusieurs utilités. Tout d'abord lorsqu'un programme est en train d'effectuer une action, elle peut servir à signaler à l'utilisateur ce que le programme fait. Elle peut aussi servir à expliquer l'utilité d'un bouton (ou d'un élément du menu). Nous allons étudier en détail le fonctionnement de ce widget nommé GtkStatusBar.

1. Utilisation d'une GtkStatusBar.

1.1 Création

La création de ce widget est aussi simple que pour tous les autres widgets. Il suffit d'utiliser cette fonction :

GtkWidget *gtk_statusbar_new(void);

1.2 Utilisation

Regardons tout d'abord comment fonctionne une GtkStatusBar. Les messages sont mis dans une pile, l'élément le plus haut de la pile étant affiché. Pour gérer cette pile, Gtk+ offre trois fonctions différentes.

Mais avant de pouvoir gérer cette pile, il faut connaître l'identifiant de la partie du programme qui ajoute un message dans la pile :

guint gtk_statusbar_get_context_id (GtkStatusbar *statusbar, const gchar *context_description);

Cette fonction va automatiquement ajouter un contexte, et renvoyer la valeur correspondante. Par la suite cet identifiant est à utiliser pour ajouter ou enlever des éléments à la pile.

Pour ajouter un élément, il n'y a qu'une seule fonction :

guint gtk_statusbar_push (GtkStatusbar *statusbar, guint context_id, const gchar *text);

statusbar : pointeur sur la barre d'état précédemment créée.
context_id : identifiant origine message.
text : message à afficher.

Après l'appel de cette fonction, le message est automatiquement ajouté en haut de la pile et est affiché dans la barre d'état. La valeur de retour correspond à l'identifiant du message dans la pile qui peut être utile pour sa suppression.

Pour supprimer un message de la pile, nous avons cette fois deux fonctions différentes :

void gtk_statusbar_pop (GtkStatusbar *statusbar, guint context_id);
void gtk_statusbar_remove (GtkStatusbar *statusbar, guint context_id, guint message_id);

La première fonction enlève l'élément le plus haut placé dans la pile provenant de la partie du programme ayant l'identifiant context_id. C'est là que context_id prend toute son importance.

La deuxième fonction enlève l'élément par son identifiant et celui de son contexte.

Nous avons maintenant tout ce qu'il faut pour utiliser une barre d'état dans notre application.

1.3 Exemple

Nous allons construire une application comportant deux boutons et barre d'état. Le but de cette application et d'afficher un message dans la barre d'état lorsque la souris survole un des boutons.

Nous allons d'abord créer notre barre d'état :

StatusBar = gtk_status_bar_new();

Ensuite nous allons l'insérer dans la fenêtre principale. En général, la barre d'état se trouve en bas d'une fenêtre, nous allons donc utiliser la fonction gtk_box_pack_end :

gtk_box_pack_end(GTK_BOX(VBox),StatusBar,FALSE,FALSE,0);

Nous allons créer deux contextes différents (un pour chaque bouton) pour l'utilisation de la barre d'état :

ContextId1 = gtk_statusbar_get_context_id(GTK_STATUSBAR(StatusBar), "ExitMsg");
ContextId2 = gtk_statusbar_get_context_id(GTK_STATUSBAR(StatusBar), "AboutMsg");

Il ne reste plus qu'à connecter les signaux "enter" et "leave" de deux boutons et écrire les fonctions callback. Dans la fonction de connexion, le ContextIdx sera passé en paramètre data, mais il faudra utiliser la macro de conversion GINT_TO_POINTER().

1.4 Programme exemple

#include <stdlib.h>
#include <gtk/gtk.h>

static GtkWidget *pStatusBar;

void OnAboutBtn(GtkWidget *pButton, GtkWidget *pWindow);
void OnExitBtnEnter(GtkWidget *pButton, gpointer iContextId);
void OnAboutBtnEnter(GtkWidget *pButton, gpointer iContextId);
void ClearStatus(GtkWidget *pButton, gpointer iContextId);

int main(int argc, char **argv)
{
    GtkWidget* pWindow;
    GtkWidget* pVBox;
    GtkWidget* pExitButton;
    GtkWidget *pAboutButton;
    guint iContextId1;
    guint iContextId2;

    gtk_init(&argc, &argv);

    pWindow = gtk_window_new(GTK_WINDOW_TOPLEVEL);
    gtk_window_set_default_size(GTK_WINDOW(pWindow), 320, 200);
    gtk_window_set_title(GTK_WINDOW(pWindow), "GtkStatusbar");
    g_signal_connect(G_OBJECT(pWindow), "destroy", G_CALLBACK(gtk_main_quit), NULL);

    pVBox=gtk_vbox_new(FALSE,5);
    gtk_container_add(GTK_CONTAINER(pWindow), pVBox);

    pExitButton=gtk_button_new_with_label("Quitter");
    gtk_box_pack_start(GTK_BOX(pVBox), pExitButton, TRUE, FALSE, 5);
    g_signal_connect(G_OBJECT(pExitButton), "clicked", G_CALLBACK(gtk_main_quit), NULL);

    pAboutButton=gtk_button_new_with_label("A propos...");
    gtk_box_pack_start(GTK_BOX(pVBox), pAboutButton, TRUE, FALSE, 5);
    g_signal_connect(G_OBJECT(pAboutButton), "clicked", G_CALLBACK(OnAboutBtn), pWindow);

    /* Creation de la barre d'etat */
    pStatusBar = gtk_statusbar_new();

    gtk_box_pack_end(GTK_BOX(pVBox), pStatusBar, FALSE, FALSE, 0);

    /* Creation des contextes */
    iContextId1 = gtk_statusbar_get_context_id(GTK_STATUSBAR(pStatusBar), "ExitMsg");
    iContextId2 = gtk_statusbar_get_context_id(GTK_STATUSBAR(pStatusBar), "AboutMsg");

    g_signal_connect(G_OBJECT(pExitButton), "enter", G_CALLBACK(OnExitBtnEnter),
        GINT_TO_POINTER(iContextId1));
    g_signal_connect(G_OBJECT(pAboutButton), "enter", G_CALLBACK(OnAboutBtnEnter),
        GINT_TO_POINTER(iContextId2));
    g_signal_connect(G_OBJECT(pExitButton), "leave", G_CALLBACK(ClearStatus),
        GINT_TO_POINTER(iContextId1));
    g_signal_connect(G_OBJECT(pAboutButton), "leave", G_CALLBACK(ClearStatus),
        GINT_TO_POINTER(iContextId2));

    gtk_widget_show_all(pWindow);

    gtk_main();

    return EXIT_SUCCESS;
}

void OnAboutBtn(GtkWidget *pButton, GtkWidget *pWindow)
{
    GtkWidget *pAboutDlg;

    pAboutDlg = gtk_message_dialog_new (GTK_WINDOW(pWindow),
        GTK_DIALOG_MODAL,
        GTK_MESSAGE_INFO,
        GTK_BUTTONS_OK,
        "Cours GTK+ 2.0\n"
        "GtkStatusbar\n"
        "http://gtk.developpez.com");

    gtk_dialog_run(GTK_DIALOG(pAboutDlg));

    gtk_widget_destroy(pAboutDlg);
}

void OnExitBtnEnter(GtkWidget *pButton, gpointer iContextId)
{
    /* Ajout d'un message */
    gtk_statusbar_push (GTK_STATUSBAR (pStatusBar), GPOINTER_TO_INT(iContextId), "Quitter l'application");
}

void OnAboutBtnEnter(GtkWidget *pButton, gpointer iContextId)
{
    /* Ajout d'un message */
    gtk_statusbar_push (GTK_STATUSBAR (pStatusBar), GPOINTER_TO_INT(iContextId), "Informations");
}

void ClearStatus(GtkWidget *pButton, gpointer iContextId)
{
    /* Suppression d'un message */
    gtk_statusbar_pop(GTK_STATUSBAR(pStatusBar), GPOINTER_TO_INT(iContextId));
}

Résultat :





2. En savoir plus.

2.1 Signaux

text-popped
Prototype fonction callback : void user_function(GtkStatusbar *statusbar, guint context_id, gchar *text, gpointer user_data);
Ce signal est émis par la barre d'état lorsqu'un message est supprimé.
text-pushed
Prototype fonction callback : void user_function(GtkStatusbar *statusbar, guint context_id, gchar *text, gpointer user_data);
Ce signal est émis par la barre d'état lorsqu'un message est ajouté.

2.2 Fonctions documentées

void gtk_statusbar_set_has_resize_grip(GtkStatusbar *statusbar, gboolean setting);
Définit si la zone à droite de la barre permet de redimensionner la fenêtre conteneur.
Entrée(s) :
statusbar : la barre d'état.
setting : TRUE pour oui, FALSE sinon.
Sortie : rien.
gboolean gtk_statusbar_get_has_resize_grip(GtkStatusbar *statusbar);
Pour savoir si la barre d'état permet de redimensionner la fenêtre conteneur.
Entrée(s) :
statusbar : la barre d'état.
Sortie : TRUE si oui, FALSE sinon.

Date de mise à jour : 17 mai 2003