Наши партнеры

UnixForum





Библиотека сайта rus-linux.net

Программирование с использованием gtkmm 3. Меню и панели инструментов

Оригинал: Programming with gtkmm 3
Авторы: Murray Cumming, Bernhard Rieder, Jonathon Jongsma, Ole Laursen, Marko Anastasov, Daniel Elstner, Chris Vine, David King, Pedro Ferreira, Kjell Ahlstedt
Дата публикации: 15 Октября 2013 г.
Перевод: А.Панин
Дата перевода: 15 марта 2014 г.

Хотя и существуют специальные API для создания меню и панелей инструментов, вам в большинстве случаев придется работать с ними одновременно, используя менеджер пользовательского интерфейса (UIManager) для описания действий (Actions), которые впоследствии вы сможете связывать с меню и панелями инструментов. Таким образом вы сможете обрабатывать события активации действия вместо обработки событий активации элементов меню и панели инструментов по отдельности. Также вы сможете включать и отключать элементы меню и панели инструментов одновременно с помощью действия.

Работа с рассматриваемыми элементами пользовательского интерфейса предусматривает необходимость использования классов Gtk::ActionGroup, Gtk::Action и Gtk::UIManager, экземпляры которых должны создаваться с помощью методов create(), возвращающих умные указатели RefPtr.

12.1. Действия (Actions)

В первую очередь следует создать действия (на основе класса Gtk::Action) и добавить их в группу действий (представленную классом Gtk::ActionGroup) с помощью метода Gtk::ActionGroup::add().

Аргументы метода Gtk::Action::create() позволяют задать имя действия, а также способ его отображения в меню и на панелях инструментов. Следует использовать стандартные элементы там, где это возможно для того, чтобы избавится от необходимости задания текста названия, акселератора, иконки и текста всплывающей подсказки, а также для использования существующих стандартных переводов.

Вы можете установить обработчик сигналов при вызове метода ActionGroup::add(). Этот обработчик сигналов будет функционировать в моменты активации действия с помощью элемента меню или кнопки на панели инструментов.

Учтите, что вам придется задавать действия для элементов подменю наряду с действиями для элементов меню.

Пример реализации описанных действий представлен ниже:
m_refActionGroup = Gtk::ActionGroup::create();

m_refActionGroup->add( Gtk::Action::create("MenuFile", "_Файл") );
m_refActionGroup->add( Gtk::Action::create("New", Gtk::Stock::NEW),
  sigc::mem_fun(*this, &ExampleWindow::on_action_file_new) );
m_refActionGroup->add( Gtk::Action::create("ExportData", "Экспортировать данные"),
  sigc::mem_fun(*this, &ExampleWindow::on_action_file_open) );
m_refActionGroup->add( Gtk::Action::create("Quit", Gtk::Stock::QUIT),
  sigc::mem_fun(*this, &ExampleWindow::on_action_file_quit) );

Следует помнить о том, что заданные нами имена действий из данного кода будут видимы пользователям в меню и на панелях инструментов. Следовательно, в рамках данного кода вы должны задействовать механизм перевода строк, поместив строки в макрос _(). Конечно же, в тех случаях, когда мы используем стандартные элементы Gtk::Stock, перевод будет доступен автоматически.

12.2. Менеджер пользовательского интерфейса (UIManager)

На следующем этапе вам придется создать объект менеджера пользовательского интерфейса (на основе класса Gtk::UIManager) и добавить созданную группу действий (на основе класса Gtk::ActionGroup) в этот менеджер с помощью метода insert_action_group(). На этом этапе также полезно сообщить родительскому окну о необходимости генерации событий в ответ на активацию определенных клавиатурных сочетаний с помощью метода add_accel_group().

Пример реализации описанных действий представлен ниже:
Glib::RefPtr<Gtk::UIManager> m_refUIManager =
    Gtk::UIManager::create();
m_refUIManager->insert_action_group(m_refActionGroup);
add_accel_group(m_refUIManager->get_accel_group());
После этого вы можете непосредственно описать расположение элементов меню и панелей инструментов, а затем добавить описание элементов пользовательского интерфейса в менеджер пользовательского интерфейса. Для этого "строкового описания пользовательского интерфейса" используется формат XML, причем вы должны использовать имена уже созданных вами действий. Например, это может быть сделано следующим образом:
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);

Помните о том, что все эти имена являются всего лишь идентификаторами, которые мы использовали при создании действий. Они не представляют текст, который пользователь увидит в меню и на панелях инструментов. Мы передавали эти читаемые пользователем имена в процессе создания действий.

Для создания экземпляров классов Gtk::MenuBar или Gtk::ToolBar, которые будут представлять на самом деле видимые виджеты, вы должны использовать метод Gtk::UIManager::get_widget(), после чего добавлять полученный виджет в контейнер. Например, это может быть сделано следующим образом:
Gtk::Widget* pMenubar = m_refUIManager->get_widget("/MenuBar");
pBox->add(*pMenuBar, Gtk::PACK_SHRINK);

12.3. Всплывающие меню (Popup Menu)

В обычных условиях меню просто добавляются в окно, но они также могут временно показываться в результате нажатия на кнопку мыши. К примеру, контекстное меню может быть показано в момент, когда пользователь нажимает правую кнопку мыши.

Строка размещения элементов меню для менеджера пользовательского интерфейса должна включать элемент "popup". Например, эта строка может выглядеть следующим образом:
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);
Для показа всплывающего меню следует использовать метод popup() объекта на основе класса Gtk::Menu, передавая идентификатор кнопки и время активации, предоставляемые обработчиком сигнала "button_press_event", который вам придется обрабатывать в любом случае. Пример обработчика:
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; //Обработка произведена.
  }
  else
    return false;
}

12.4. Примеры

12.4.1. Пример создания главного меню

Рисунок 12-1: Главное меню
Главное меню

Исходный код

Файл: examplewindow.h (Для использования совместно с gtkmm 3, а не с gtkmm 2)

Файл: examplewindow.cc (Для использования совместно с gtkmm 3, а не с gtkmm 2)

Файл: main.cc (Для использования совместно с gtkmm 3, а не с gtkmm 2)

12.4.2. Пример создания всплывающего меню

Рисунок 12-2: Всплывающее меню
Всплывающее меню

Исходный код

Файл: examplewindow.h (Для использования совместно с gtkmm 3, а не с gtkmm 2)

Файл: examplewindow.cc (Для использования совместно с gtkmm 3, а не с gtkmm 2)

Файл: main.cc (Для использования совместно с gtkmm 3, а не с gtkmm 2)


Следующий раздел : 13. Палитра инструментов (ToolPalette).