Book HomePHP CookbookSearch this book

20.9. Displaying Menus

20.9.1. Problem

You want to display a menu bar at the top of a GTK window.

20.9.2. Solution

Create a GtkMenu. Create individual GtkMenuItem objects for each menu item you want to display and add each menu item to the GtkMenu with append( ). Then, create a root menu GtkMenuItem with the label that should appear in the menu bar (e.g., "File" or "Options"). Add the menu to the root menu with set_submenu( ). Create a GtkMenuBar and add the root menu to the menu bar with append( ). Finally, add the menu bar to the window:

// create the window
$window = &new GtkWindow();

// create a menu
$menu = &new GtkMenu();

// create a menu item and add it to the menu
$menu_item_1 = &new GtkMenuItem('Open');
$menu->append($menu_item_1);

// create another menu item and add it to the menu
$menu_item_2 = &new GtkMenuItem('Close');
$menu->append($menu_item_2);

// create yet another menu item and add it to the menu
$menu_item_2 = &new GtkMenuItem('Save');
$menu->append($menu_item_2);

// create a root menu and add the existing menu to it
$root_menu = &new GtkMenuItem('File');
$root_menu->set_submenu($menu);

// create a menu bar and add the root menu to it
$menu_bar = &new GtkMenuBar();
$menu_bar->append($root_menu);

// add the menu bar to the window
$window->add($menu_bar);

// display the window
$window->show_all();

// necessary so that the program exits properly
function shutdown() { gtk::main_quit(); }
$window->connect('destroy','shutdown');

// start GTK's signal handling loop
gtk::main();

20.9.3. Discussion

A menu involves a hierarchy of quite a few objects. The GtkWindow (or another container) holds the GtkMenuBar. The GtkMenuBar holds a GtkMenuItem for each top-level menu in the menu bar (e.g., "File," "Options," or "Help"). Each top-level GtkMenuItem has a GtkMenu as a submenu. That submenu contains each GtkMenuItem that should appear under the top-level menu.

As with any GTK widget, a GtkMenuItem object can have callbacks that handle signals. When a menu item is selected, it triggers the activate signal. To take action when a menu item is selected, connect its activate signal to a callback. Here's a version of the button-and-label time display from Recipe 20.8 with two menu items: "Update," which updates the time in the label, and "Quit," which quits the program:

// create the window
$window = &new GtkWindow();

// create a container for the label and the button
$container = &new GtkVBox();

// create a menu
$menu = &new GtkMenu();

// create a menu item and add it to the menu
$menu_item_1 = &new GtkMenuItem('Update');
$menu->append($menu_item_1);

// create another menu item and add it to the menu
$menu_item_2 = &new GtkMenuItem('Quit');
$menu->append($menu_item_2);

// create a root menu and add the existing menu to it
$root_menu = &new GtkMenuItem('File');
$root_menu->set_submenu($menu);

// create a menu bar and add the root menu to it
$menu_bar = &new GtkMenuBar();
$menu_bar->append($root_menu);

// add the menu to the container
$container->add($menu_bar);

// create a label showing the time
$label = &new GtkLabel(strftime('%c'));

// add the label to the container
$container->pack_start($label);

// create a button
$button = &new GtkButton('Update Time');

/* set the update_time() function as the callback for the "clicked" signal
   and pass $label to the callback */
$button->connect('clicked','update_time',$label);

function update_time($b,$lb) {
    $lb->set_text(strftime('%c'));
}

// add the button to the container
$container->pack_start($button);

// when the Update menu item is selected, call update_time()
$menu_item_1->connect('activate','update_time',$label);

// when the Quit menu item is selected, quit
$menu_item_2->connect('activate','shutdown');

// add the container to the window
$window->add($container);

// display the window
$window->show_all();

// necessary so that the program exits properly
function shutdown() { gtk::main_quit(); }
$window->connect('destroy','shutdown');

// start GTK's signal handling loop
gtk::main();

Callbacks are connected to the menu items with their connect( ) methods. The callbacks are connected to the activate signals towards the end of the code because the call to $menu_item_1->connect( ) passes $label to update_time( ) . For $label to be successfully passed to update_time( ) while the program is running, connect( ) has to be called after $label is instantiated.

20.9.4. See Also

Documentation on the GtkMenu class at http://gtk.php.net/manual/en/gtk.gtkmenu.php, GtkMenuShell::append( ) at http://gtk.php.net/manual/en/gtk.gtkmenushell.method. append.php, the GtkMenuItem class at http://gtk.php.net/manual/en/gtk.gtkmenuitem. php, GtkMenuItem::set_submenu( ) at http://gtk.php.net/manual/en/gtk.gtkmenuitem. method.set_submenu.php, GtkMenuItem's activate signal at http://gtk.php.net/manual/en/gtk.gtkmenuitem.signal.activate.php, and the GtkMenuBar class at http://gtk.php.net/manual/en/gtk.gtkmenubar.php.



Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.