22 мая 2009 г.

Создаём меню окна. Часть 1.

Меню является неотъемлимой частью практически любой программы. И не удивительно, ведь это универсальное средство, посредством которого пользователь может взаимодействовать с программой.

Сегодня вы научитесь создавать меню, распологать в нём подпункты и выполнять определённые действия при нажатии на соответствующий пункт. В конце у нас получится примерно следующее:


За меню отвечает класс GtkMenuBar(). Создадим его и сразу же поместим в контейнер, чтобы не забыть:
$menubar = new GtkMenuBar();
$vbox->pack_start($menubar, FALSE, FALSE, 0);

Четвёртым параметром указываются отступы сверху и снизу от элемента в пикселях (т.к. мы используем GtkVBox(), для GtkHBox() отступы будут справа и слева). По-умолчанию этот параметр имеет значение 1 и окно будет иметь следующий вид (не очень приятный):


Теперь создадим пункты меню:
$file = new GtkMenuItem('_Файл');
$edit = new GtkMenuItem('_Правка');
$help = new GtkMenuItem('_Справка');
 
$menubar->append($file);
$menubar->append($edit);
$menubar->append($help);
Метод append(), как вы догадались, помещает пункты на панель.
Если на этом этапе остановиться и запустить программу, то мы увидим панель меню с тремя пунктами: "Файл", "Правка", "Сравка", но при их нажатии ничего не происходит. Нам необходимо для каждого из пунктов добавить подменю:
$sub_file = new GtkMenu();
$file->set_submenu($sub_file);
$sub_edit = new GtkMenu();
$edit->set_submenu($sub_edit);
$sub_help = new GtkMenu();
$help->set_submenu($sub_help);

Если вы запустите программу на текущем этапе разработки, то увидите, что при клике по пунктам меню открывается пустое подменю. Нам остаётся только добавить в него необходимые пункты (с помощью метода append()) и создать обработчик нажатия на пункты подменю (сигнал 'activate').
$quit = new GtkMenuItem('_Выход');
$quit->connect_simple('activate', array('Gtk', 'main_quit'));
$sub_file->append($quit);
 
$options = new GtkMenuItem('_Параметры');
$options->connect('activate', 'on_activate');
$sub_edit->append($options);
 
$about = new GtkMenuItem('_О программе');
$about->connect('activate', 'on_activate');
$sub_help->append($about);
 
function on_activate($menu)
{
echo $menu->child->get_label()."\n";
}


Полный код программы:
<?php
 
$window = new GtkWindow();
$window->set_position(Gtk::WIN_POS_CENTER);
$window->set_size_request(200, -1);
$window->connect_simple('destroy', array('Gtk', 'main_quit'));
 
$vbox = new GtkVBox();
 
$menubar = new GtkMenuBar();
$vbox->pack_start($menubar, FALSE, FALSE, 0);
 
$file = new GtkMenuItem('_Файл');
$edit = new GtkMenuItem('_Правка');
$help = new GtkMenuItem('_Справка');
 
$menubar->append($file);
$menubar->append($edit);
$menubar->append($help);
 
$sub_file = new GtkMenu();
$file->set_submenu($sub_file);
$sub_edit = new GtkMenu();
$edit->set_submenu($sub_edit);
$sub_help = new GtkMenu();
$help->set_submenu($sub_help);
 
$quit = new GtkMenuItem('_Выход');
$quit->connect_simple('activate', array('Gtk', 'main_quit'));
$sub_file->append($quit);
 
$options = new GtkMenuItem('_Параметры');
$options->connect('activate', 'on_activate');
$sub_edit->append($options);
 
$about = new GtkMenuItem('_О программе');
$about->connect('activate', 'on_activate');
$sub_help->append($about);
 
function on_activate($menu)
{
echo $menu->child->get_label()."\n";
}
 
$window->add($vbox);
$window->show_all();
Gtk::main();
 
?>

3 комментария:

Анонимный комментирует...

Спасибо за тутор, но хорошо было бы ещё пояснить код.
Например не ясно, зачем нуже аргумент "Ноль" в конце выхова метода pack_start()
"pack_start($menubar, FALSE, FALSE, 0);"

Shecspi комментирует...

Как-то пропустил этот момент.
Четвёртым параметром указываются отступы сверху и снизу от элемента в пикселях (т.к. мы используем GtkVBox(), для GtkHBox() отступы будут справа и слева). По-умолчанию этот параметр имеет значение 1 и окно будет иметь следующий вид (не очень приятный):
http://lh6.ggpht.com/_kff0W9u6lhw/Shlm_haa6jI/AAAAAAAAAN0/LfjyDBtzqm8/s800/screenshot1.png

Shecspi комментирует...

Добавил эту поправку в статью. Спасибо.