Menus et barres d'outils
There are specific APIs for Menus and toolbars, but you should usually deal with them together, using the UIManager to define Actions which you can then arrange in menus and toolbars. In this way you can handle activation of the action instead of responding to the menu and toolbar items separately. And you can enable or disable both the menu and toolbar item via the action.
Cette façon d'opérer implique l'utilisation des classes Gtk::ActionGroup, Gtk::Action et UIManager ; chacune d'entre elles sera instanciée avec la fonction membre create() qui renverra un pointeur RefPtr.

Actions
Créez tout d'abord un objet Action et ajoutez-le à un ActionGroup avec ActionGroup::add().
The arguments to Action::create() specify the action's name and how it will appear in menus and toolbars.
Vous pouvez également indiquer le gestionnaire de signal lors de l'appel à ActionGroup::add(). Ce gestionnaire de signal sera appelé quand l'action sera activée par l'intermédiaire, soit de l'élément de menu, soit du bouton de la barre d'outils.
Notez que vous devez définir des actions pour les éléments de sous-menus de la même manière que pour les menus.
Par exemple :

m_refActionGroup = Gtk::ActionGroup::create();

m_refActionGroup->add( Gtk::Action::create("MenuFile", "_File") );
m_refActionGroup->add( Gtk::Action::create("New", "_New"),
  sigc::mem_fun(*this, &ExampleWindow::on_action_file_new) );
m_refActionGroup->add( Gtk::Action::create("ExportData", "Export Data"),
  sigc::mem_fun(*this, &ExampleWindow::on_action_file_open) );
m_refActionGroup->add( Gtk::Action::create("Quit", "_Quit"),
  sigc::mem_fun(*this, &ExampleWindow::on_action_file_quit) );

Note that this is where we specify the names of the actions as they will be seen by users in menus and toolbars. Therefore, this is where you should make strings translatable, by putting them inside the _() macro.

UIManager
Vous devez ensuite créer un UIManager dans lequel vous ajoutez les objets ActionGroup avec insert_action_group(). Il est judicieux d'indiquer à cet instant à la fenêtre parent de répondre aux raccourcis claviers avec la fonction membre add_accel_group().
Par exemple,

Glib::RefPtr<Gtk::UIManager> m_refUIManager =
    Gtk::UIManager::create();
m_refUIManager->insert_action_group(m_refActionGroup);
add_accel_group(m_refUIManager->get_accel_group());

Puis, vous définissez la disposition réelle de l'affichage des menus et des barres d'outils en insérant l'agencement de l'UI dans l'UIManager. Cette « chaîne ui » utilise un format XML dans lequel vous mentionnez le nom des actions que vous venez de créer. Par exemple :

Glib::ustring ui_info =
    "<ui>"
    "  <menubar name='MenuBar'>"
    "    <menu action='MenuFile'>"
    "      <menuitem action='New'/>"
    "      <menuitem action='Open'/>"
    "      <separator/>"
    "      <menuitem action='Quit'/>"
    "    </menu>"
    "    <menu action='MenuEdit'>"
    "      <menuitem action='Cut'/>"
    "      <menuitem action='Copy'/>"
    "      <menuitem action='Paste'/>"
    "    </menu>"
    "  </menubar>"
    "  <toolbar  name='ToolBar'>"
    "    <toolitem action='Open'/>"
    "    <toolitem action='Quit'/>"
    "  </toolbar>"
    "</ui>";

m_refUIManager->add_ui_from_string(ui_info);

Souvenez-vous que ces noms sont uniquement les identifiants utilisés lors de la création des actions. Ce n'est pas le texte que l'utilisateur verra dans les menus et les barres d'outils. Nous avons indiqué les libellés lisibles par l'utilisateur lors de la création des actions.
Pour créer un objet Gtk::MenuBar ou Gtk::Toolbar que vous pouvez vraiment afficher, utilisez la fonction membre UIManager::get_widget() et ajoutez l'élément graphique dans un conteneur. Par exemple :

Gtk::Widget* pMenubar = m_refUIManager->get_widget("/MenuBar");
pBox->add(*pMenuBar, Gtk::PACK_SHRINK);

Menus contextuels
Normalement, les menus sont seulement ajoutés à une fenêtre, mais ils peuvent aussi être temporairement affichés lors d'un clic de souris. Par exemple, un menu contextuel peut s'afficher si l'utilisateur clique sur un élément avec le bouton droit de la souris.
La présentation UI d'un menu contextuel utilise la balise popup. Par exemple :

Glib::ustring ui_info =
    "<ui>"
    "  <popup name='PopupMenu'>"
    "    <menuitem action='ContextEdit'/>"
    "    <menuitem action='ContextProcess'/>"
    "    <menuitem action='ContextRemove'/>"
    "  </popup>"
    "</ui>";

m_refUIManager->add_ui_from_string(ui_info);

Pour afficher le menu contextuel, utilisez la fonction membre popup() de la classe Gtk::Menu. Vous indiquez l'identifiant du bouton de souris et le délai d'activation tels que fournis par le signal button_press_event, signal que vous devez gérer de toutes façons. Par exemple :

bool ExampleWindow::on_button_press_event(GdkEventButton* event)
{
  if( (event->type == GDK_BUTTON_PRESS) &&
      (event->button == 3) )
  {
    m_Menu_Popup->popup(event->button, event->time);
    return true; // Il est géré.
  }
  else
    return false;
}

Exemples

Exemple de menu principal

Menu principal
Source Code
File: examplewindow.h (For use with gtkmm 3, not gtkmm 2)

#ifndef GTKMM_EXAMPLEWINDOW_H
#define GTKMM_EXAMPLEWINDOW_H

#include <gtkmm.h>

class ExampleWindow : public Gtk::Window
{
public:
  ExampleWindow();
  virtual ~ExampleWindow();

protected:
  //Signal handlers:
  void on_menu_file_new_generic();
  void on_menu_file_quit();
  void on_menu_others();

  void on_menu_choices(const Glib::ustring& parameter);
  void on_menu_choices_other(int parameter);
  void on_menu_toggle();

  //Child widgets:
  Gtk::Box m_Box;

  Glib::RefPtr<Gtk::Builder> m_refBuilder;

  //Two sets of choices:
  Glib::RefPtr<Gio::SimpleAction> m_refChoice, m_refChoiceOther;

  Glib::RefPtr<Gio::SimpleAction> m_refToggle;
};

#endif //GTKMM_EXAMPLEWINDOW_H

File: examplewindow.cc (For use with gtkmm 3, not gtkmm 2)

#include "examplewindow.h"
#include <iostream>

ExampleWindow::ExampleWindow()
: m_Box(Gtk::ORIENTATION_VERTICAL)
{
  set_title("main menu example");
  set_default_size(200, 200);

  add(m_Box); // put a MenuBar at the top of the box and other stuff below it.

  //Create actions for menus and toolbars:
  Glib::RefPtr<Gio::SimpleActionGroup> refActionGroup =
    Gio::SimpleActionGroup::create();

  //File|New sub menu:
  refActionGroup->add_action("newstandard",
    sigc::mem_fun(*this, &ExampleWindow::on_menu_file_new_generic));

  refActionGroup->add_action("newfoo",
    sigc::mem_fun(*this, &ExampleWindow::on_menu_file_new_generic));

  refActionGroup->add_action("newgoo",
    sigc::mem_fun(*this, &ExampleWindow::on_menu_file_new_generic));

  //File menu:
  refActionGroup->add_action("quit",
    sigc::mem_fun(*this, &ExampleWindow::on_menu_file_quit));

  //Edit menu:
  refActionGroup->add_action("copy",
    sigc::mem_fun(*this, &ExampleWindow::on_menu_others));
  refActionGroup->add_action("paste",
    sigc::mem_fun(*this, &ExampleWindow::on_menu_others));
  refActionGroup->add_action("something",
    sigc::mem_fun(*this, &ExampleWindow::on_menu_others));


  //Choices menus, to demonstrate Radio items,
  //using our convenience methods for string and int radio values:
  m_refChoice = refActionGroup->add_action_radio_string("choice",
    sigc::mem_fun(*this, &ExampleWindow::on_menu_choices),
    "a");

  m_refChoiceOther = refActionGroup->add_action_radio_integer("choiceother",
    sigc::mem_fun(*this, &ExampleWindow::on_menu_choices_other),
    1);

  m_refToggle = refActionGroup->add_action_bool("sometoggle",
    sigc::mem_fun(*this, &ExampleWindow::on_menu_toggle),
    false);


  //Help menu:
  refActionGroup->add_action("about",
    sigc::mem_fun(*this, &ExampleWindow::on_menu_others) );

  insert_action_group("example", refActionGroup);

  m_refBuilder = Gtk::Builder::create();

  //TODO: add_accel_group(m_refBuilder->get_accel_group());

  //Layout the actions in a menubar and toolbar:
  Glib::ustring ui_info =
    "<interface>"
    "  <menu id='menu-example'>"
    "    <submenu>"
    "      <attribute name='label' translatable='yes'>_File</attribute>"
    "      <section>"
    "        <item>"
    "          <attribute name='label' translatable='yes'>New _Standard</attribute>"
    "          <attribute name='action'>example.newstandard</attribute>"
    "          <attribute name='accel'>&lt;Primary&gt;n</attribute>"
    "        </item>"
    "        <item>"
    "          <attribute name='label' translatable='yes'>New _Foo</attribute>"
    "          <attribute name='action'>example.newfoo</attribute>"
    "        </item>"
    "        <item>"
    "          <attribute name='label' translatable='yes'>New _Goo</attribute>"
    "          <attribute name='action'>example.newgoo</attribute>"
    "        </item>"
    "      </section>"
    "      <section>"
    "        <item>"
    "          <attribute name='label' translatable='yes'>_Quit</attribute>"
    "          <attribute name='action'>example.quit</attribute>"
    "          <attribute name='accel'>&lt;Primary&gt;q</attribute>"
    "        </item>"
    "      </section>"
    "    </submenu>"
    "    <submenu>"
    "      <attribute name='label' translatable='yes'>_Edit</attribute>"
    "      <section>"
    "        <item>"
    "          <attribute name='label' translatable='yes'>_Copy</attribute>"
    "          <attribute name='action'>example.copy</attribute>"
    "          <attribute name='accel'>&lt;Primary&gt;c</attribute>"
    "        </item>"
    "        <item>"
    "          <attribute name='label' translatable='yes'>_Paste</attribute>"
    "          <attribute name='action'>example.paste</attribute>"
    "          <attribute name='accel'>&lt;Primary&gt;v</attribute>"
    "        </item>"
    "        <item>"
    "          <attribute name='label' translatable='yes'>_Something</attribute>"
    "          <attribute name='action'>example.something</attribute>"
    "        </item>"
    "      </section>"
    "    </submenu>"
    "    <submenu>"
    "      <attribute name='label' translatable='yes'>_Choices</attribute>"
    "      <section>"
    "        <item>"
    "          <attribute name='label' translatable='yes'>Choice _A</attribute>"
    "          <attribute name='action'>example.choice</attribute>"
    "          <attribute name='target'>a</attribute>"
    "        </item>"
    "        <item>"
    "          <attribute name='label' translatable='yes'>Choice _B</attribute>"
    "          <attribute name='action'>example.choice</attribute>"
    "          <attribute name='target'>b</attribute>"
    "        </item>"
    "      </section>"
    "    </submenu>"
    "    <submenu>"
    "      <attribute name='label' translatable='yes'>_Other Choices</attribute>"
    "      <section>"
    "        <item>"
    "          <attribute name='label' translatable='yes'>Choice 1</attribute>"
    "          <attribute name='action'>example.choiceother</attribute>"
    "          <attribute name='target' type='i'>1</attribute>"
    "        </item>"
    "        <item>"
    "          <attribute name='label' translatable='yes'>Choice 2</attribute>"
    "          <attribute name='action'>example.choiceother</attribute>"
    "          <attribute name='target' type='i'>2</attribute>"
    "        </item>"
    "      </section>"
    "      <section>"
    "        <item>"
    "          <attribute name='label' translatable='yes'>Some Toggle</attribute>"
    "          <attribute name='action'>example.sometoggle</attribute>"
    "        </item>"
    "      </section>"
    "    </submenu>"
    "    <submenu>"
    "      <attribute name='label' translatable='yes'>_Help</attribute>"
    "      <section>"
    "        <item>"
    "          <attribute name='label' translatable='yes'>_About</attribute>"
    "          <attribute name='action'>example.about</attribute>"
    "        </item>"
    "      </section>"
    "    </submenu>"
    "  </menu>"
    "</interface>";

  try
  {
    m_refBuilder->add_from_string(ui_info);
  }
  catch(const Glib::Error& ex)
  {
    std::cerr << "building menus failed: " <<  ex.what();
  }

  //Get the menubar and add it to a container widget:
  Glib::RefPtr<Glib::Object> object =
    m_refBuilder->get_object("menu-example");
  Glib::RefPtr<Gio::Menu> gmenu =
    Glib::RefPtr<Gio::Menu>::cast_dynamic(object);
  if(!gmenu)
    g_warning("GMenu not found");

  //Menubar:
  Gtk::MenuBar* pMenubar = Gtk::manage(new Gtk::MenuBar(gmenu));
  m_Box.pack_start(*pMenubar, Gtk::PACK_SHRINK);


  //Create the toolbar and add it to a container widget:
  Gtk::Toolbar* toolbar = Gtk::manage(new Gtk::Toolbar());
  Gtk::ToolButton* button = Gtk::manage(new Gtk::ToolButton());
  button->set_icon_name("document-new");
  //We can't do this until we can break the ToolButton ABI: button->set_detailed_action_name("example.new");
  gtk_actionable_set_detailed_action_name (GTK_ACTIONABLE (button->gobj()), "example.newstandard");
  toolbar->add(*button);

  button = Gtk::manage(new Gtk::ToolButton());
  button->set_icon_name("application-exit");
  //We can't do this until we can break the ToolButton ABI: button->set_detailed_action_name("example.quit");
  gtk_actionable_set_detailed_action_name (GTK_ACTIONABLE (button->gobj()), "example.quit");
  toolbar->add(*button);

  m_Box.pack_start(*toolbar, Gtk::PACK_SHRINK);

  show_all_children();
}

ExampleWindow::~ExampleWindow()
{
}

void ExampleWindow::on_menu_file_quit()
{
  hide(); //Closes the main window to stop the app->run().
}

void ExampleWindow::on_menu_file_new_generic()
{
   std::cout << "A File|New menu item was selected." << std::endl;
}

void ExampleWindow::on_menu_others()
{
  std::cout << "A menu item was selected." << std::endl;
}

void ExampleWindow::on_menu_choices(const Glib::ustring& parameter)
{
  //The radio action's state does not change automatically:
  m_refChoice->change_state(parameter);
  
  Glib::ustring message;
  if(parameter == "a")
    message = "Choice a was selected.";
  else
    message = "Choice b was selected";

  std::cout << message << std::endl;
}

void ExampleWindow::on_menu_choices_other(int parameter)
{
  //The radio action's state does not change automatically:
  m_refChoiceOther->change_state(parameter);

  Glib::ustring message;
  if(parameter == 1)
    message = "Choice 1 was selected.";
  else
    message = "Choice 2 was selected";

  std::cout << message << std::endl;
}

void ExampleWindow::on_menu_toggle()
{
  bool active = false;
  m_refToggle->get_state(active);

  //The toggle action's state does not change automatically:
  m_refToggle->change_state(!active);
  active = !active;

  Glib::ustring message;
  if(active)
    message = "Toggle is active.";
  else
    message = "Toggle is not active";

  std::cout << message << std::endl;
}

File: main.cc (For use with gtkmm 3, not gtkmm 2)

#include "examplewindow.h"
#include <gtkmm/application.h>

int main(int argc, char *argv[])
{
  Glib::RefPtr<Gtk::Application> app = Gtk::Application::create(argc, argv, "org.gtkmm.example");

  ExampleWindow window;

  //Shows the window and returns when it is closed.
  return app->run(window);
}

Exemple de menu contextuel

Menu contextuel
Source Code
File: examplewindow.h (For use with gtkmm 3, not gtkmm 2)

#ifndef GTKMM_EXAMPLEWINDOW_H
#define GTKMM_EXAMPLEWINDOW_H

#include <gtkmm.h>

class ExampleWindow : public Gtk::Window
{
public:
  ExampleWindow();
  virtual ~ExampleWindow();

protected:
  //Signal handlers:
  virtual bool on_button_press_event(GdkEventButton* event);
  void on_menu_file_popup_generic();

  //Child widgets:
  Gtk::Box m_Box;
  Gtk::EventBox m_EventBox;
  Gtk::Label m_Label;

  Glib::RefPtr<Gtk::Builder> m_refBuilder;

  Gtk::Menu* m_pMenuPopup;
};

#endif //GTKMM_EXAMPLEWINDOW_H

File: examplewindow.cc (For use with gtkmm 3, not gtkmm 2)

#include "examplewindow.h"
#include <iostream>

ExampleWindow::ExampleWindow()
: m_Box(Gtk::ORIENTATION_VERTICAL),
  m_Label("Right-click to see the popup menu."),
  m_pMenuPopup(0)
{
  set_title("popup example");
  set_default_size(200, 200);

  add(m_Box);

  //Add an event box that can catch button_press events:
  m_Box.pack_start(m_EventBox);
  m_EventBox.signal_button_press_event().connect(sigc::mem_fun(*this,
              &ExampleWindow::on_button_press_event) );

  m_EventBox.add(m_Label);

  //Create actions:

  //Fill menu:

  Glib::RefPtr<Gio::SimpleActionGroup> refActionGroup =
    Gio::SimpleActionGroup::create();

  //File|New sub menu:
  //These menu actions would normally already exist for a main menu, because a
  //context menu should not normally contain menu items that are only available
  //via a context menu.

  refActionGroup->add_action("edit",
    sigc::mem_fun(*this, &ExampleWindow::on_menu_file_popup_generic));

  refActionGroup->add_action("process", //TODO: How to specify "<control>P" as an accelerator. 
    sigc::mem_fun(*this, &ExampleWindow::on_menu_file_popup_generic));

  refActionGroup->add_action("remove",
    sigc::mem_fun(*this, &ExampleWindow::on_menu_file_popup_generic));

  insert_action_group("examplepopup", refActionGroup);


  m_refBuilder = Gtk::Builder::create();

  //Layout the actions in a menubar and toolbar:
  Glib::ustring ui_info =
    "<interface>"
    "  <menu id='menu-examplepopup'>"
    "    <section>"
    "      <item>"
    "        <attribute name='label' translatable='yes'>Edit</attribute>"
    "        <attribute name='action'>examplepopup.edit</attribute>"
    "      </item>"
    "      <item>"
    "        <attribute name='label' translatable='yes'>Process</attribute>"
    "        <attribute name='action'>examplepopup.process</attribute>"
    "      </item>"
    "      <item>"
    "        <attribute name='label' translatable='yes'>Remove</attribute>"
    "        <attribute name='action'>examplepopup.remove</attribute>"
    "      </item>"
    "    </section>"
    "  </menu>"
    "</interface>";

  try
  {
    m_refBuilder->add_from_string(ui_info);
  }
  catch(const Glib::Error& ex)
  {
    std::cerr << "building menus failed: " <<  ex.what();
  }

  //Get the menu:
  Glib::RefPtr<Glib::Object> object =
    m_refBuilder->get_object("menu-examplepopup");
  Glib::RefPtr<Gio::Menu> gmenu =
    Glib::RefPtr<Gio::Menu>::cast_dynamic(object);
  if(!gmenu)
    g_warning("GMenu not found");

  m_pMenuPopup = new Gtk::Menu(gmenu);

  show_all_children();
}

ExampleWindow::~ExampleWindow()
{
}

void ExampleWindow::on_menu_file_popup_generic()
{
   std::cout << "A popup menu item was selected." << std::endl;
}

bool ExampleWindow::on_button_press_event(GdkEventButton* event)
{
  if( (event->type == GDK_BUTTON_PRESS) && (event->button == 3) )
  {
    if(!m_pMenuPopup->get_attach_widget())
    {
      m_pMenuPopup->attach_to_widget(*this);
    }

    if(m_pMenuPopup)
      m_pMenuPopup->popup(event->button, event->time);


    return true; //It has been handled.
  }
  else
    return false;
}

File: main.cc (For use with gtkmm 3, not gtkmm 2)

#include "examplewindow.h"
#include <gtkmm/application.h>

int main(int argc, char *argv[])
{
  Glib::RefPtr<Gtk::Application> app = Gtk::Application::create(argc, argv, "org.gtkmm.example");

  ExampleWindow window;

  //Shows the window and returns when it is closed.
  return app->run(window);
}