| |
GTK+ 2.0 Tutorial |
||
---|---|---|
Menu Widget |
После рассмотрения сложного пути создания меню, рассмотрим как это же можно сделать при помощи вызова функции gtk_item_factory.
ItemFactory создаёт меню из массива записей ItemFactory. Это означает, что вы можете определить ваше меню в его самой простой форме и затем создать виджеты (меню/строки) меню с минимумом запросов функции.
В ядре ItemFactory находится ItemFactoryEntry. Эта структура определяет один пункт меню и когда массив этих записей определен, целое меню сформировано. Структура записей ItemFactory выглядит так:
struct _GtkItemFactoryEntry { gchar *path; gchar *accelerator; GtkItemFactoryCallback callback; guint callback_action; gchar *item_type; }; |
Каждая строка определяет часть пункта меню.
*path - определяет путь и название пункта меню, например: "/File/Open" было бы именем пункта меню который подходит для записи ItemFactory с путём "/File". Однако пункт "/File/Open" был бы показан в меню File как "Open", потому что первые "/" используются для определения пути и не могут присутствовать в имени пункта. Символ, которому предшествует символ подчеркивания, указывает акселератор (сокращенная клавиша) в открытом меню.
*accelerator является строкой, которая указывает ключевую комбинацию клавиш и используется как ярлык к пункту меню. Строка может состоять из единичного символа или комбинации модификаторов и символов.
Модификаторами клавиш могут быть:
"<ALT> - alt "<CTL>" или "<CTRL>" или "<CONTROL>" - control "<MOD1>" до "<MOD5>" - modn "<SHFT>" или "<SHIFT>" - shift |
"<ConTroL>a" "<SHFT><ALT><CONTROL>X" |
callback - функция вызываемая при создании пунктом меню сигнала "activate". Форма обратного вызова описана в разделе Callback Description.
Значение callback_action помещается в функцию обратного вызова. Прототип функции смотрите в разделе Callback Description.
item_type - является строкой, которая определяет тип виджета упакованного в контейнер пунктов меню. Возможные значения:
Отметьте, что <LastBranch> полезен только для одного подменю строки меню.
Обратный вызов для ItemFactory entry может иметь две формы. Если callback_action равен 0 (zero), он имеет следующую форму:
void callback(void) |
другая форма:
void callback(gpointer callback_data, guint callback_action, GtkWidget *widget) |
callback_data - является указателем на произвольную часть данных и установлен вызовом gtk_item_factory_create_items().
callback_action - некоторое значение callback_action в ItemFactory записях.
*widget - указатель на виджет пункта меню (подробности в Manual Menu Creation).
Создаём простой пункт меню:
GtkItemFactoryEntry entry = {"/_File/_Open...", "<CTRL>O", print_hello, 0, "<Item>"}; |
Здесь создаётся простой пункт меню "/File/Open" (отображается как "Open"), внутри строки меню "/File". Он имеет акселератор (shortcut) control+'O' при нажатии которого вызывается функция print_hello(). print_hello() имеет форму void print_hello(void) так как callback_action имеет значение zero. Если 'O' в "Open" подчеркнута, то при открытом меню и нажатой клавише 'O' пункт будет активизирован. Заметьте, что "File/_Open" может быть использован как путь вместо "/_File/_Open".
Создание входа с более сложным обратным вызовом (callback):
GtkItemFactoryEntry entry = {"/_View/Display _FPS", NULL, print_state, 7,"<CheckItem>"}; |
Это определяет новый пункт меню отображаемый как "Display FPS" в вышестоящем пункте меню "View". При нажатии вызывается функция print_state(). Так как callback_action не равно zero print_state() имеет форму:
void print_state(gpointer callback_data, guint callback_action, GtkWidget *widget) |
с callback_action равным 7.
Создаём установку кнопки выбора:
GtkItemFactoryEntry entry1 = {"/_View/_Low Resolution", NULL, change_resolution, 1, "<RadioButton>"}; GtkItemFactoryEntry entry2 = {"/_View/_High Resolution", NULL, change_resolution, 2, "/View/Low Resolution"}; |
entry1 определяет одиночную кнопку выбора которая переключает вызов функции change_resolution() с параметром callback_action равным 1. change_resolution() имеет форму:
void change_resolution(gpointer callback_data, guint callback_action, GtkWidget *widget) |
entry2 определяет кнопку выбора которая принадлежит группе в которой находится entry1. Она вызывает туже самую функцию при переключении, но параметр callback_action равен 2. Обратите внимание на отсутствие акселераторов. Если бы потребовалась ещё одна кнопка выбора для переключения, то её можно было бы создать таким же образом в этой же группе с item_type равным "/View/Low Resolution".
Массив записей для определения меню. Ниже приведен пример объявления массива:
static GtkItemFactoryEntry entries[] = { { "/_File", NULL, NULL, 0, "<Branch>" }, { "/File/tear1", NULL, NULL, 0, "<Tearoff>" }, { "/File/_New", "<CTRL>N", new_file, 1, "<Item>" }, { "/File/_Open...", "<CTRL>O", open_file, 1, "<Item>" }, { "/File/sep1", NULL, NULL, 0, "<Seperator>" }, { "/File/_Quit", "<CTRL>Q", quit_program, 0, "<Item>"} }; |
Массив GtkItemFactoryEntry пунктов определяет меню. Функция выглядит так:
GtkItemFactory* gtk_item_factory_new( GtkType container_type, const gchar *path, GtkAccelGroup *accel_group ); |
container_type может иметь следующие значения:
GTK_TYPE_MENU GTK_TYPE_MENU_BAR GTK_TYPE_OPTION_MENU |
container_type определяет тип нужного вам меню, например - всплывающее меню, панель меню или меню опций (как поле со списком но с выпавшим меню).
path определяет путь к основному меню. В основном уникальное имя основного меню должно быть заключено в треугольные скобки "<>". Это важно для обозначения акселераторов. Оно должно быть уникальным и для каждого меню и для каждой программы. Например программа с именем 'foo', может иметь главное меню "<FooMain>", а всплывающее меню "<FooImagePopUp>", или нечто похожее. Главное чтобы они были уникальны.
accel_group указатель на gtk_accel_group. Таблицы акселераторов устанавливаются в то время как генерируется меню. Новая группа акселераторов создаётся функцией gtk_accel_group_new().
Но это - только первый шаг. Чтобы преобразовывать массив информации GtkItemFactoryEntry в виджеты, используется следующая функция :
void gtk_item_factory_create_items( GtkItemFactory *ifactory, guint n_entries, GtkItemFactoryEntry *entries, gpointer callback_data ); |
*ifactory - указатель на вышеупомянутое созданное производство пунктов.
n_entries - является числом входов в массив GtkItemFactoryEntry..
*entries - указатель на массив GtkItemFactoryEntry.
callback_data - является тем, что передают во все функции обратного вызова для всех входов с callback_action != 0.
Группа акселераторов создана, теперь нужно прикрепить меню к окну:
void gtk_window_add_accel_group( GtkWindow *window, GtkAccelGroup *accel_group); |
Следующая функция извлекает виджеты из ItemFactory:
GtkWidget* gtk_item_factory_get_widget( GtkItemFactory *ifactory, const gchar *path ); |
Например, если ItemFactory имеет две записи "/File", и "/file/new", используя дорожку "/File" извлечётся виджет menu из ItemFactory. Используя путь "/File/New" извлечётся виджет menu item. Это позволяет установить начальное состояние пунктов меню. Например для установки по умолчанию кнопки выбора в путь "/Shape/Oval", код будет выглядеть так:
gtk_check_menu_item_set_active( GTK_CHECK_MENU_ITEM (gtk_item_factory_get_item (item_factory, "/Shape/Oval")), TRUE); |
Для извлечения основного меню используется функция gtk_item_factory_get_item() с путем "<main>" (в независимости от использованного пути в gtk_item_factory_new()). В случае ItemFactory, создаваемого с типом GTK_TYPE_MENU_BAR, возвращается виджет панели меню. Если тип GTK_TYPE_MENU возвращается виджет меню. Если тип GTK_TYPE_OPTION_MENU возвращается виджет меню опций.
Помните: вход определенный путем "/_File" фактически путь "/File".
Теперь вы имеете строку меню или меню и можете манипулировать ими как обсуждалось в разделе Manual Menu Creation.
Manual Menu Example |
Item Factory Example |
Закладки на сайте Проследить за страницей |
Created 1996-2024 by Maxim Chirkov Добавить, Поддержать, Вебмастеру |