Menubar and Toolbar

Next you should create a Gtk::Builder. At this point is also a good idea to tell the application to respond to keyboard shortcuts, by using Gtk::Application::set_accel_for_action().

For instance,

Glib::RefPtr<Gtk::Builder> m_refBuilder = Gtk::Builder::create();

app->set_accel_for_action("", "<Primary>n");
app->set_accel_for_action("example.quit", "<Primary>q");
app->set_accel_for_action("example.copy", "<Primary>c");
app->set_accel_for_action("example.paste", "<Primary>v");

If your main window is derived from ApplicationWindow and you instantiate your menubar with Gtk::Application::set_menubar(), then you don't have to call set_accel_for_action(). See Application Menu and Main Menu example for an example.

Then, you can define the actual visible layout of the menus and toolbars, and add the UI layout to the Builder. This "ui string" uses an XML format, in which you should mention the names of the actions that you have already created. For instance:

const char* ui_info =
  "  <menu id='menubar'>"
  "    <submenu>"
  "      <attribute name='label' translatable='yes'>_File</attribute>"
  "      <section>"
  "        <item>"
  "          <attribute name='label' translatable='yes'>_New</attribute>"
  "          <attribute name='action'></attribute>"
  "          <attribute name='accel'>&lt;Primary&gt;n</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>"
  "      <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>"
  "    </submenu>"
  "  </menu>"


This is where we specify the names of the menu items as they will be seen by users in the menu. Therefore, this is where you should make strings translatable, by adding translatable='yes'.

To instantiate a Gtk::MenuBar and Gtk::Toolbar which you can actually show, you should use the Builder::get_object() and Builder::get_widget() methods, and then add the widgets to a container. For instance:

Glib::RefPtr<Glib::Object> object = m_refBuilder->get_object("menubar");
Glib::RefPtr<Gio::Menu> gmenu = Glib::RefPtr<Gio::Menu>::cast_dynamic(object);
Gtk::MenuBar* pMenuBar = Gtk::make_managed<Gtk::MenuBar>(gmenu);
m_Box.pack_start(*pMenuBar, Gtk::PACK_SHRINK);

Gtk::Toolbar* toolbar = nullptr;
m_refBuilder->get_widget("toolbar", toolbar);
m_Box.pack_start(*toolbar, Gtk::PACK_SHRINK);