Aller au menu - Aller au contenu

Icône Menus, barres d'outils, barre d'état

Avatar
Mise à jour : 28/01/2012
Difficulté : Intermédiaire Intermédiaire Durée d'étude : 2 heures
522 visites depuis 7 jours, dont 20 sur ce chapitre classé 219/786
La plupart des applications contiennent un menu, une ou des barres d'outils et, parfois, une barre d'état (vous savez, l'endroit situé en bas de la fenêtre qui affiche des informations que nous savons déjà :D ).

C'est dans ce chapitre que vous apprendrez à créer tout cela.
Sommaire du chapitre :
Icône du chapitre
Chapitre précédent Sommaire

Les menus

Les classes


Dans cette partie, nous allons créer une barre de menus.

Pour ce faire, nous allons avoir besoin de plusieurs classes.

La première est, bien sûr, Gtk::MenuBar, qui représente une barre de menu.
Une barre de menu contient des étiquettes alignées horizontalement :
Image utilisateur
Barre de menu contenant les menus Fichier et Édition.


Le menu est représenté par la classe Gtk::Menu.
Un menu est un ensemble d’item de menu, représenté verticalement :
Image utilisateur
Un menu comportant divers item de menu (Nouveau, Récents, Ouvrir, …).


Enfin, les items de menu sont représentés par la classe Gtk::MenuItem.
Les items de menu sont constitués le plus souvent d’une étiquette (texte) et d’une image.
Nous pouvons attribuer une mnémonique et un raccourci aux items de menu.

Une mnémonique est une combinaison de touche permettant de naviguer dans les menus. Par exemple, Alt-F ouvre le menu fichier et Alt-Q active l’item de menu Quitter (il faut pour cela que le menu fichier soit affiché).

Un raccourci permet d’activer un item de menu sans le voir.
Par exemple, Ctrl-Q quitte l’application.


Plusieurs classes dérivent de Gtk::MenuItem :

Nous ne verrons que les deux premiers.
Vous pourrez facilement comprendre les trois autres grâce à la documentation.

Avant de passer à la suite, voici un schéma représentant les différentes classes sur l’image précédente :
Image utilisateur

Le code


La barre de menu


Créer une barre de menu est très simple :
Code : C++
1
Gtk::MenuBar barreMenu;


Le menu


Nous ne pouvons pas ajouter un menu directement à la barre de menu ; il faut ajouter un item de menu à cette dernière (retourner voir le schéma si vous l’avez déjà oublié :p ).

Donc, nous allons créer un item de menu et l’ajouter à la barre de menu :
Code : C++
1
2
Gtk::MenuItem menuItemFichier("Fichier");
barreMenu.append(menuItemFichier);

Nous pouvons spécifier une mnémonique à l’item en précédent d’un trait de soulignement (_) le caractères souhaité et en passant true au deuxième paramètre :
Code : C++
1
Gtk::MenuItem menuItemFichier("_Fichier", true);


Ensuite, nous devons créer notre menu et l’ajouter à l’item de menu voulu :
Code : C++
1
2
Gtk::Menu menuFichier;
menuItemFichier.set_submenu(menuFichier);

Il faut utiliser set_submenu() pour ajouter un menu à un item.
Cette méthode permet donc de créer des sous-menus (voir l’item de menu Récents de l’exemple).

Les items de menu


Maintenant, nous avons un menu, mais il est un peu… :euh: … vide.
Ajoutons-lui des items.

Vous avez déjà vu comment créer un item de menu lorsque nous avons créé le menu Fichier.
Pour en ajouter un à un menu, c’est exactement la même chose :
Code : C++
1
2
Gtk::MenuItem menuItemFichiersRecents("_Récents", true);
menuFichier.append(menuItemFichiersRecents);


Mais il est possible de faire plus beau, grâce à la classe Gtk::ImageMenuItem.
Créons un item de menu Nouveau avec une belle petite image à côté (tout cela grâce aux Stock Items :) ) :
Code : C++
1
2
Gtk::ImageMenuItem menuNouveau(Gtk::Stock::NEW);
menuFichier.append(menuNouveau);

En utilisant un Stock Item, non seulement l’image et le texte est affiché, mais les raccourci et mnémonique sont également gérés. Merveilleux, non ?


Le signal à connaître pour les items de menu est activate(), qui est émit lorsque l’item de menu est cliqué ou lors de l’appel de la méthode activate() de l’item.

Séparateur


L’ajout d’un séparateur est très simple :
Code : C++
1
2
Gtk::SeparatorMenuItem separateur;
menuFichier.append(separateur);


Exemple


C’est le temps de voir un exemple :
Code : C++
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
#include <gtkmm/box.h>
#include <gtkmm/imagemenuitem.h>
#include <gtkmm/main.h>
#include <gtkmm/menu.h>
#include <gtkmm/menubar.h>
#include <gtkmm/menuitem.h>
#include <gtkmm/separatormenuitem.h>
#include <gtkmm/stock.h>
#include <gtkmm/window.h>

int main(int argc, char* argv[]) {
    Gtk::Main app(argc, argv);
    Gtk::Window fenetre;
    fenetre.resize(200, 75);
    
    Gtk::VBox boiteV;
    fenetre.add(boiteV);
    
    //Création d’une barre de menu.
    Gtk::MenuBar barreMenu;
    boiteV.pack_start(barreMenu, Gtk::PACK_SHRINK);
    
    //Création de l’item menu fichier et ajout à la barre de menu.
    Gtk::MenuItem menuItemFichier("_Fichier", true);
    barreMenu.append(menuItemFichier);
    
    //Création du menu Fichier et ajout à l’item de menu Fichier.
    Gtk::Menu menuFichier;
    menuItemFichier.set_submenu(menuFichier);
    
    //Création d’un item de menu à partir d’un Stock Item et ajout au menu.
    Gtk::ImageMenuItem menuNouveau(Gtk::Stock::NEW);
    menuFichier.append(menuNouveau);
    
    //Sous-menu : Fichier->Récents
    Gtk::MenuItem menuItemFichiersRecents("_Récents", true);
    menuFichier.append(menuItemFichiersRecents);
    
    //Utilisation de set_submenu() afin de créer un sous-menu.
    Gtk::Menu menuRecents;
    menuItemFichiersRecents.set_submenu(menuRecents);
    
    Gtk::MenuItem fichierRecent1("Fichier récent 1");
    menuRecents.append(fichierRecent1);
    Gtk::MenuItem fichierRecent2("Fichier récent 2");
    menuRecents.append(fichierRecent2);
    
    //Fichier->Ouvrir
    Gtk::ImageMenuItem menuOuvrir(Gtk::Stock::OPEN);
    menuFichier.append(menuOuvrir);
    
    //Fichier->Enregistrer
    Gtk::ImageMenuItem menuEnregistrer(Gtk::Stock::SAVE);
    menuFichier.append(menuEnregistrer);
    
    //Ajout d’un séparateur au menu Fichier.
    Gtk::SeparatorMenuItem separateur;
    menuFichier.append(separateur);
    
    //Fichier->Fermer
    Gtk::ImageMenuItem menuFermer(Gtk::Stock::CLOSE);
    menuFichier.append(menuFermer);
    
    //Fichier->Quitter
    Gtk::ImageMenuItem menuQuitter(Gtk::Stock::QUIT);
    //Connexion du clic sur le menu Quitter à la fonction Gtk::Main::quit().
    menuQuitter.signal_activate().connect(sigc::ptr_fun(&Gtk::Main::quit));
    menuFichier.append(menuQuitter);
    
    //Menu édition
    Gtk::MenuItem menuItemEdition("É_dition", true);
    barreMenu.append(menuItemEdition);
    
    Gtk::Menu menuEdition;
    menuItemEdition.set_submenu(menuEdition);
    
    fenetre.show_all();
    Gtk::Main::run(fenetre);
    return 0;
}

Dans cet exemple, nous créons une barre de menu comportant deux items de menu (donc deux menus).
Le menu fichier comporte un item ayant un sous-menu.
En effet, si l’on pointe la souris sur l’item Récents, nous voyons un autre menu s’afficher.

Passons aux barres d’outils !

Les barres d'outils

Classes


Les classes utiles à la création d’une barre d’outils sont Gtk::ToolBar et Gtk::ToolButton.

La barre d’outils


La barre d’outils est représentée par la classe Gtk::ToolBar.
Une barre d’outils contient des boutons alignés horizontalement.

Les items de barre d’outils


Les items sont représentés par la classe Gtk::ToolItem.
Mais, bien souvent, nous utiliserons une de ses classes filles :

Nous verrons les deux premières classes de cette liste.

Les items sont donc des boutons ou des séparateurs.

Le code


La barre d’outils


Encore une fois, créer une barre d’outils est très simple :
Code : C++
1
Gtk::Toolbar barreOutils;


Les items


Il existe plusieurs façon de créer des boutons pour une barre d’outils.
L’une d’entre elles consiste à fournir une chaîne de caractères au constructeur :
Code : C++
1
Gtk::ToolButton boutonCompiler("Compiler");


Pour ajouter un bouton à la barre d’outils, il faut, encore, utiliser la méthode append() :
Code : C++
1
barreOutils.append(boutonCompiler);


Il est également possible de créer un bouton à partir d’un Stock Item :
Code : C++
1
Gtk::ToolButton boutonNouveau(Gtk::Stock::NEW);


Info-bulle


Nous pouvons ajouter une info-bulle aux boutons de deux façons.
La première façon consiste à appeler la méthode set_tooltip_text() :
Code : C++
1
boutonNouveau.set_tooltip_text("Crée un nouveau fichier");

Ce texte ne doit pas utiliser le Pango Markup Language.

Si nous voulons utiliser ce langage, nous devons appeler la méthode suivante :
Code : C++
1
boutonNouveau.set_tooltip_markup("<b>Nouveau</b> fichier");


Le principal signal à connaître pour ce bouton est clicked().

Le séparateur


Il se crée très simplement, d’une façon très semblable aux séparateurs de menu :
Code : C++
1
2
Gtk::SeparatorToolItem separateur;
barreOutils.append(separateur);


Exemple


Code : C++
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
#include <gtkmm/box.h>
#include <gtkmm/main.h>
#include <gtkmm/separatortoolitem.h>
#include <gtkmm/stock.h>
#include <gtkmm/toolbar.h>
#include <gtkmm/toolbutton.h>
#include <gtkmm/window.h>

int main(int argc, char* argv[]) {
    Gtk::Main app(argc, argv);
    Gtk::Window window;
    window.resize(200, 75);
    
    Gtk::VBox vBox;
    window.add(vBox);
    
    //Création d’une barre d’outils.
    Gtk::Toolbar barreOutils;
    vBox.pack_start(barreOutils, Gtk::PACK_SHRINK);
    
    //Création d’un bouton à partir d’un Stock Item et ajout à la barre d’outils.
    Gtk::ToolButton boutonNouveau(Gtk::Stock::NEW);
    boutonNouveau.set_tooltip_text("Crée un nouveau fichier");
    barreOutils.append(boutonNouveau);
    
    Gtk::ToolButton boutonCompiler("Compiler");
    barreOutils.append(boutonCompiler);
    
    //Création d’un séparateur et ajout à la barre d’outils.
    Gtk::SeparatorToolItem separateur;
    barreOutils.append(separateur);
    
    Gtk::ToolButton boutonQuitter(Gtk::Stock::QUIT);
    boutonQuitter.set_tooltip_markup("<b><span color='red'>Ferme l’application</span></b>");
    //Connexion du signal clicked() du bouton à la fonction Gtk::Main::quit().
    boutonQuitter.signal_clicked().connect(sigc::ptr_fun(&Gtk::Main::quit));
    barreOutils.append(boutonQuitter);
    
    window.show_all();
    Gtk::Main::run(window);
    return 0;
}

Il n’y a rien de compliquer dans ce code ; vous devriez le comprendre facilement avec l’aide des commentaires.

Si l’on utilise les mêmes items pour le menu et la barre d’outils, cette façon de faire duplique beaucoup de code (création d’items pour le menu, connexion des items du menu à des fonctions de rappel, création d’items pour la barre d’outils, connexion des items de la barre d’outils à des fonctions de rappel). Ça devient vite répétitif.
Y a-t-il moyen d’éviter la répétition du code ?

Oui.
Pour cela, il faut utiliser des…

Actions


Les actions permettent de créer des items de menu et des items de barre d’outils rapidement.
En utilisant des actions, nous n’aurons pas à créer deux items et faire deux connexions de signal pour chaque item présent dans le menu et la barre d’outils.

Création


La création de signal peut se faire de plusieurs façons.
Celle permettant de créer un signal à partir d’un Stock Item est :
Code : C++
1
Glib::RefPtr<Gtk::Action> actionNouveau = Gtk::Action::create("nouveau", Gtk::Stock::NEW);

Pour créer une action à partir d’une chaîne de caractère (représentant l’étiquette), il faut faire ceci :
Code : C++
1
Glib::RefPtr<Gtk::Action> actionCompiler = Gtk::Action::create("ouvrir", "Compiler");


Nous pouvons également créer une action avec une étiquette différente et une info-bulle de cette façon :
Code : C++
1
Glib::RefPtr<Gtk::Action> actionQuitter = Gtk::Action::create("quitter", Gtk::Stock::QUIT, "Quitter l’application", "Ferme l’application");


Signal


La connexion du signal d’une action se fait de la même manière qu’avec un item de menu :
Code : C++
1
actionQuitter->signal_activate().connect(sigc::ptr_fun(&Gtk::Main::quit));


Items


Après avoir créé l’action, nous pouvons obtenir les items de menu et de barre d’outils comme suit :
Code : C++
1
2
Gtk::MenuItem* menuItem = actionNouveau->create_menu_item();
Gtk::ToolItem* toolItem = actionNouveau->create_tool_item();

Ensuite, nous pouvons les ajouter au menu et à la barre d’outils.

Exemple


Voici un exemple où les actions sont utilisées pour créer un menu et une barre d’outils :
Code : C++
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
#include <gtkmm/action.h>
#include <gtkmm/box.h>
#include <gtkmm/main.h>
#include <gtkmm/menu.h>
#include <gtkmm/menubar.h>
#include <gtkmm/menuitem.h>
#include <gtkmm/separatormenuitem.h>
#include <gtkmm/separatortoolitem.h>
#include <gtkmm/stock.h>
#include <gtkmm/toolbar.h>
#include <gtkmm/toolbutton.h>
#include <gtkmm/window.h>

int main(int argc, char* argv[]) {
    Gtk::Main app(argc, argv);
    Gtk::Window fenetre;
    fenetre.resize(200, 75);
    
    Gtk::VBox boiteV;
    fenetre.add(boiteV);
    
    /*
     * Actions
     */
    //Création d’une action à partir d’un Stock Item.
    Glib::RefPtr<Gtk::Action> actionNouveau = Gtk::Action::create("nouveau", Gtk::Stock::NEW);
    Glib::RefPtr<Gtk::Action> actionOuvrir = Gtk::Action::create("ouvrir", Gtk::Stock::OPEN);
    //Création d’une action à partir d’un texte.
    Glib::RefPtr<Gtk::Action> actionCompiler = Gtk::Action::create("ouvrir", "Compiler");
    //Création d’une action avec une info-bulle.
    Glib::RefPtr<Gtk::Action> actionQuitter = Gtk::Action::create("quitter", Gtk::Stock::QUIT, "Quitter l’application", "Ferme l’application");
    
    //Connexion d’une action à une fonction de rappel.
    actionQuitter->signal_activate().connect(sigc::ptr_fun(&Gtk::Main::quit));
    
    /*
     * Menu
     */
    Gtk::MenuBar barreMenu;
    boiteV.pack_start(barreMenu, Gtk::PACK_SHRINK);
    
    Gtk::MenuItem menuItemFichier("Fichier");
    barreMenu.append(menuItemFichier);
    
    Gtk::Menu menuFichier;
    menuItemFichier.set_submenu(menuFichier);
    
    //Ajout d’actions au menu fichier.
    menuFichier.append(*(actionNouveau->create_menu_item()));
    menuFichier.append(*(actionOuvrir->create_menu_item()));
    menuFichier.append(*(actionCompiler->create_menu_item()));
    
    Gtk::SeparatorMenuItem separateurMenu;
    menuFichier.append(separateurMenu);
    
    menuFichier.append(*(actionQuitter->create_menu_item()));
    
    /*
     * Barre d’outils
     */
    Gtk::Toolbar barreOutils;
    boiteV.pack_start(barreOutils, Gtk::PACK_SHRINK);
    
    //Ajout d’actions à la barre d’outils.
    barreOutils.append(*(actionNouveau->create_tool_item()));
    barreOutils.append(*(actionOuvrir->create_tool_item()));
    barreOutils.append(*(actionCompiler->create_tool_item()));
    
    //Création d’un séparateur et ajout à la barre d’outils.
    Gtk::SeparatorToolItem separateurBarreOutils;
    barreOutils.append(separateurBarreOutils);
    
    barreOutils.append(*(actionQuitter->create_tool_item()));
    
    fenetre.show_all();
    Gtk::Main::run(fenetre);
    return 0;
}

Encore une fois, il n’y a rien de bien compliqué et vous comprendrez facilement avec les commentaires.

Si vous comptez utiliser les actions pour des items de type case à cocher ou bouton radio, assurez-vous d’utiliser la bonne classe pour l’action.
Regardez les classe filles d’action telles que Gtk::ToggleAction et Gtk::RadioAction.

Le gestionnaire d'interface utilisateur

Le gestionnaire d’interface utilisateur est une façon de créer des menus et des barres d’outils à partir d’une description XML.

Syntaxe


Les balises que nous allons utiliser sont les suivantes :
  • <ui> : la balise racine du document XML ;
  • <menubar> : balise représentant une barre de menu ;
  • <menu> : balise représentant un menu ;
  • <menuitem> : balise représentant un item de menu ;
  • <separator/> : balise représentant un séparateur d’items de menu ou de barre d’outils ;
  • <toolbar> : balise représentant une barre d’outils ;
  • <toolitem> : balise représentant un item de barre d’outils.

Nous pouvons préciser l’attribut name pour la barre d’outils et la barre de menu afin de faciliter sa récupération depuis le code C++.
En outre, nous devons préciser l’attribut action des <menu>, <menuitem> et <toolitem>.

Voici un exemple de ce fichier XML :
Code : XML
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
<ui>
    <menubar name="barreMenu">
        <menu action="fichier">
            <menuitem action="nouveau"/>
            <menuitem action="ouvrir"/>
            <separator/>
            <menuitem action="quitter"/>
        </menu>
    </menubar>
    <toolbar name="barreOutils">
        <toolitem action="nouveau"/>
        <toolitem action="ouvrir"/>
        <separator/>
        <toolitem action="quitter"/>
    </toolbar>
</ui>


Gestionnaire d’interface utilisateur


Le gestionnaire d’interface utilisateur est représenté par la classe Gtk::UIManager.
Pour instancier un objet Gtk::UIManager, il suffit de faire :
Code : C++
1
Glib::RefPtr<Gtk::UIManager> uiManager = Gtk::UIManager::create();

Ensuite, nous pouvons lui faire lire le fichier de description XML avec :
Code : C++
1
uiManager->add_ui_from_file("menuBarreOutils.ui");


Puis, nous pouvons récupérer la barre d’outils et la barre de menu grâce à la méthode get_widget() :
Code : C++
1
2
Gtk::Widget* barreMenu = uiManager->get_widget("/barreMenu");
Gtk::Widget* barreOutils = uiManager->get_widget("/barreOutils");

Le paramètre est le chemin vers le widget voulu.
La racine est facultative. Le code suivant est identique :
Code : C++
1
Gtk::Widget* barreOutils = uiManager->get_widget("/ui/barreOutils");

Le code suivant récupère l’item de barre d’outils Nouveau :
Code : C++
1
Gtk::Widget* toolitemNouveau = uiManager->get_widget("/barreOutils/nouveau");


Finalement, nous pouvons ajouter les barres à notre boîte verticale :
Code : C++
1
2
boiteV.pack_start(*barreMenu, Gtk::PACK_SHRINK);
boiteV.pack_start(*barreOutils, Gtk::PACK_SHRINK);


Groupe d’actions


Nous avons spécifié des actions dans la description XML.
Par conséquent, il faudra créer les actions ayant pour nom ceux spécifiés dans le XML.
Dans la partie précédente, nous avons créé des actions.
Pour rappel, nous avons fait comme ceci :
Code : C++
1
Glib::RefPtr<Gtk::Action> actionNouveau = Gtk::Action::create("nouveau", Gtk::Stock::NEW);

Le premier paramètre de la fonction create() est le nom de l’action.
Le même nom que dans la description XML.

Les actions créées devront être liées au gestionnaire d’interface utilisateur.
Pour ce faire, nous allons avoir besoin de créer un groupe d’actions.

Un groupe d’actions ce crée comme ceci :
Code : C++
1
Glib::RefPtr<Gtk::ActionGroup> groupe = Gtk::ActionGroup::create();


Nous pouvons lier le groupe d’actions avec le gestionnaire de cette façon :
Code : C++
1
uiManager->insert_action_group(groupe);


Si vous oublier de lier vos actions au gestionnaire d’interface utilisateur, vos items de menu et de barre d’outils ne seront pas créés.
De plus, vous aurez une erreur comme celle-ci à l’exécution :

Code : Console
(UiManager:2471): Gtk-WARNING **: quitter: missing action quitter


Après avoir créé le groupe, nous devons y ajouter des actions.
Pour cela, nous devons utiliser la méthode add() :
Code : C++
1
groupe->add(actionNouveau);

Bien souvent, comme nous n’utiliserons plus les actions par la suite, nous allons ajouter les actions comme ceci :
Code : C++
1
groupe->add(Gtk::Action::create("fichier", "Fichier"));

Si nous voulons, en plus d’ajouter l’action au groupe, indiquer la fonction de rappel, nous pouvons ajouter un deuxième paramètre à cette méthode :
Code : C++
1
groupe->add(Gtk::Action::create("quitter", Gtk::Stock::QUIT, "Quitter l’application", "Ferme l’application"), sigc::ptr_fun(&Gtk::Main::quit));


Groupe d’accélérations


Un groupe d’accélérations est un groupe de raccourcis clavier.
Bien souvent, un tel groupe sera attaché à une fenêtre.

Le problème que nous avons en utilisant un gestionnaire d’interface utilisateur est que les raccourcis clavier lui sont propres.
Par conséquent, nous devons les transférer à la fenêtre pour que celle-ci puisse réagir à ces raccourcis.
Pour ce faire, nous allons utiliser la méthode suivante :
Code : C++
1
fenetre.add_accel_group(uiManager->get_accel_group());

Ainsi, nous ajoutons le groupe d’accélérations du gestionnaire à la fenêtre.

Si vous oubliez cette ligne, vos raccourcis ne fonctionneront plus.


Exemple


Voici un exemple mettant en application ce que vous venez de voir :
Code : C++
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
#include <gtkmm/action.h>
#include <gtkmm/box.h>
#include <gtkmm/main.h>
#include <gtkmm/stock.h>
#include <gtkmm/uimanager.h>
#include <gtkmm/window.h>

int main(int argc, char* argv[]) {
    Gtk::Main app(argc, argv);
    Gtk::Window fenetre;
    
    Gtk::VBox boiteV;
    fenetre.add(boiteV);
    
    //Création d’un groupe d’actions.
    Glib::RefPtr<Gtk::ActionGroup> groupe = Gtk::ActionGroup::create();
    //Création d’actions et ajout au groupe.
    groupe->add(Gtk::Action::create("fichier", "Fichier"));
    groupe->add(Gtk::Action::create("nouveau", Gtk::Stock::NEW));
    groupe->add(Gtk::Action::create("ouvrir", Gtk::Stock::OPEN));
    //Il est possible de spécifier une fonction de rappel au deuxième paramètre de la méthode add().
    groupe->add(Gtk::Action::create("quitter", Gtk::Stock::QUIT, "Quitter l’application", "Ferme l’application"), sigc::ptr_fun(&Gtk::Main::quit));
    
    //Création d’un gestionnaire d’interface utilisateur.
    Glib::RefPtr<Gtk::UIManager> uiManager = Gtk::UIManager::create();
    uiManager->insert_action_group(groupe);
    uiManager->add_ui_from_file("menuBarreOutils.ui");
    //Pour que la fenêtre réagisse aux raccourcis-clavier des actions, il faut lui ajouter un groupe d’accélération (raccourcis).
    fenetre.add_accel_group(uiManager->get_accel_group());
    
    Gtk::Widget* barreMenu = uiManager->get_widget("/barreMenu");
    boiteV.pack_start(*barreMenu, Gtk::PACK_SHRINK);
    
    Gtk::Widget* barreOutils = uiManager->get_widget("/barreOutils");
    boiteV.pack_start(*barreOutils, Gtk::PACK_SHRINK);
    
    fenetre.show_all();
    
    Gtk::Main::run(fenetre);
    return 0;
}

La barre d'état

La barre d’état permet d’afficher des informations sur l’état de l’application.
Elle est représentée par la classe Gtk::Statusbar.

Création


La création d’une telle barre se fait assez facilement :
Code : C++
1
Gtk::Statusbar barreEtat;


Utilisation


Nous pouvons ajouter ou enlever des messages dans une barre d’état.

Pour en ajouter un, il faut utiliser la méthode push() :
Code : C++
1
int messageID = barreEtat.push("Vous pouvez commencer à utiliser l’application");

Comme vous pouvez le constater, cette méthode renvoie un identifiant.
Cela est utile s’il vous prend l’envie de supprimer le message :
Code : C++
1
barreEtat.remove_message(messageID);


Il est également possible de supprimer tous les messages :
Code : C++
1
barreEtat.remove_all_messages();


Pourquoi supprimer tous les messages ?
Il ne peut y en avoir qu’un qui est affiché à l’écran, non ?

Il ne peut, en effet, qu’y avoir un message à la fois.
Par contre, la barre d’état contient une pile de message.
Par conséquent, le dernier message ajouté (avec push()) sera affiché.
Les autres n’apparaîtront pas.
Si nous enlevons le message affiché, l’avant-dernier message ajouté s’affichera et ainsi de suite.

Exemple


Voici un exemple d’utilisation de la barre d’état.
Ce programme affiche un message lorsque l’utilisateur pointe la souris sur le bouton.
Ce message disparaît lorsque le souris ne pointe plus dessus :
Image utilisateur


Fenetre.hpp


Code : C++
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#ifndef DEF_FENETRE
#define DEF_FENETRE

#include <string>

#include <gtkmm/box.h>
#include <gtkmm/button.h>
#include <gtkmm/statusbar.h>
#include <gtkmm/stock.h>
#include <gtkmm/window.h>

class Fenetre : public Gtk::Window {
    public:
        Fenetre();
        
        bool afficherMessageEtat(GdkEventCrossing* event, std::string message);
        bool cacherMessageEtat(GdkEventCrossing* event);
        
    private:
        Gtk::Statusbar barreEtat; //Barre d’état.
        Gtk::VBox boiteV;
        Gtk::Button bouton;
};

#endif


Fenetre.cpp


Code : C++
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
#include "Fenetre.hpp"

Fenetre::Fenetre() : bouton(Gtk::Stock::QUIT) {
    add(boiteV);
    
    //Ajouter un message et récupérer son ID.
    int messageID = barreEtat.push("Vous pouvez commencer à utiliser l’application");
    //Enlever le message à partir de son ID.
    barreEtat.remove_message(messageID);
    
    boiteV.pack_start(bouton);
    
    //Connexions de signaux au bouton afin d’afficher un message dans la barre d’état lorsqu’il est survolé.
    bouton.signal_enter_notify_event().connect(sigc::bind<std::string>(sigc::mem_fun(*this, &Fenetre::afficherMessageEtat), "Quitter l’application"));
    bouton.signal_leave_notify_event().connect(sigc::mem_fun(*this, &Fenetre::cacherMessageEtat));
    
    //Un cas d’utilisation de pack_end() est l’ajout d’une barre d’état.
    boiteV.pack_end(barreEtat, Gtk::PACK_SHRINK);
    
    show_all();
}

bool Fenetre::afficherMessageEtat(GdkEventCrossing* event, std::string message) {
    (void)event;
    barreEtat.push(message);
    return true;
}

bool Fenetre::cacherMessageEtat(GdkEventCrossing* event) {
    (void)event;
    barreEtat.remove_all_messages();
    return true;
}

La seule information que vous ignorez dans ce programme est les signaux utilisés :
Le signal enter_notify_event() est émit lorsque la souris pointe sur le bouton.
Le signal leave_notify_event() est émit, quant à lui, lorsque la souris quitte le bouton.

Il est très utile d’utiliser la méthode pack_end() afin de s’assurer que la barre d’état se trouvera toujours en bas de la fenêtre.

Q.C.M.

Si une application comporte un menu Fichier avec les actions Nouveau, Ouvrir et Fermer, combien d’items de menu (Gtk::MenuItem) doit-on créer au total ?
Laquelle de ces affirmations est vraie ?
Quelle est la différence entre une mnémonique et un raccourci-clavier ?
Quelle méthode ajoute une info-bulle dans laquelle on peut y mettre du texte formatté (avec le Pango Markup Language) ?
À quoi sert le gestionnaire d’interface utilisateur (Gtk::UIManager) ?

Statistiques de réponses au QCM

Maintenant, vous pouvez vraiment dire que vous savez créer des fenêtres. Vous pouvez pratiquement créer toutes les applications que vous voulez.

Mais... (je sais que vous l'attendiez, celui-là :-° ).
Pratiquez, pratiquez, pratiquez !

Modifier votre jeu de morpion (je ne le lâcherai jamais, ce jeu :p ).
Ajoutez-lui un menu qui permet de commencer une nouvelle partie, de quitter le programme (avec une confirmation si la partie n'est pas terminé, bien sûr ^^ ).
Ajoutez-lui une barre d'outils avec les mêmes actions que dans le menu (c'est ce que tout le monde fait, non :lol: ?).
Une barre d’état indiquant l’état du jeu ne serait pas de trop non plus…

Pratiquez, car dans le prochain chapitre, vous ferez un TP. :o
Chapitre précédent Sommaire

Partager

Il n'y a pas encore de commentaire pour ce tuto.