As soon as you create more complex programs, the use of menus become almost compulsory. This lesson will discuss how to create menus.
Both Gtk2::Menu
and Gtk2::MenuBar
are subclasses of Gtk2::MenuShell
. You can not create a Gtk2::MenuShell
directly. You create either a Gtk2::Menu
, or a Gtk2::MenuBar
, or both, to help create the structure of your menus. This will give you acces the methods of Gtk2::MenuShell
.
You pack Gtk2::MenuItem
's into a Gtk2::Menu
and a Gtk2::MenuBar
. There are different kinds of Gtk2::MenuItem
s. They include the following:
Table 16-1. Available menu items
Gtk2 Class Name | Use |
---|---|
Gtk2::MenuItem | Standard menu item, may include a mnemonic to include the Alt shortcut. This is the base class from which all subsequent menuitems in this list gets derived. |
Gtk2::CheckMenuItem | This is the equivalent of a Gtk2::ToggleButton . It can be set active or not. |
Gtk2::RadioMenuItem | This is the equivalent of a Gtk2::RadioButton . When it gets created, you define a group to which it belongs. At any given instance, only one Gtk2::RadioMenuItem belonging to this group can be selected. |
Gtk2::ImageMenuItem | To give your application that extra elegance, you can use this. It can be used to pack an image in front of the menu's label. |
Gtk2::SeparatorMenuItem | This is the equivalent of a Gtk2::HSeparator . It us used to give logical grouping to menu items. |
Gtk2::TearoffMenuItem | Adding this to Gtk2::Menu , will enable you to separate this menu from its parent menu. |
We will create a demo program which incorporates all of these menu items, so you can see them in action. The demo program will also feature a popup menu. This type of menu does not require a Gtk2::MenuBar
and usually gets displayed when the right mouse button is clicked.
The program can be found here: 'gtk2_menu_basic.pl'
1 #! /usr/bin/perl -w 2 3 use strict; 4 use Gtk2 '-init'; 5 use Glib qw/TRUE FALSE/; 6 7 #standard window creation, placement, and signal connecting 8 my $window = Gtk2::Window->new('toplevel'); 9 $window->signal_connect('delete_event' => sub { Gtk2->main_quit; }); 10 $window->set_border_width(5); 11 $window->set_position('center_always'); 12 13 #this vbox will return the bulk of the gui 14 my $vbox = &ret_vbox(); 15 16 #add and show the vbox 17 $window->add($vbox); 18 $window->show(); 19 20 #our main event-loop 21 Gtk2->main(); 22 23 sub ret_vbox { 24 25 my $vbox = Gtk2::VBox->new(FALSE,5); 26 $vbox->set_size_request (300, 300); 27 28 #==================================== 29 #Start of with a Gtk2::Menu widget 30 my $menu_edit = Gtk2::Menu->new(); 31 32 #-------- 33 #add a tearoff item 34 $menu_edit->append(Gtk2::TearoffMenuItem->new); 35 36 #________ 37 #add an Image Menu item using stock 38 my $menu_item_cut = Gtk2::ImageMenuItem->new_from_stock ('gtk-cut', undef); 39 #connet to the activate signal to catch when this item is selected 40 $menu_item_cut->signal_connect('activate' => sub { print "selected the cut menu\n"}); 41 $menu_edit->append($menu_item_cut); 42 43 #_________ 44 #add a separator 45 $menu_edit->append(Gtk2::SeparatorMenuItem->new()); 46 47 #_________ 48 #add a check menu item 49 my $menu_item_toggle = Gtk2::CheckMenuItem->new('_Toggle Menu Item'); 50 #connect to the toggled signal to catch the active state 51 $menu_item_toggle->signal_connect('toggled' => \&toggle,"Toggle Menu Item"); 52 $menu_edit->append($menu_item_toggle); 53 54 #_________ 55 #add a separator 56 $menu_edit->append(Gtk2::SeparatorMenuItem->new()); 57 58 #_________ 59 #add radio menu items 60 my $menu_radio_one = Gtk2::RadioMenuItem->new(undef,'Radio one'); 61 #connect to the toggled signal to catch the changes 62 $menu_radio_one->signal_connect('toggled' => \&toggle,"Radio one"); 63 my $group = $menu_radio_one->get_group; 64 $menu_edit->append($menu_radio_one); 65 66 my $menu_radio_two = Gtk2::RadioMenuItem->new($group, 'Radio two'); 67 #connect to the toggled signal to catch the changes 68 $menu_radio_two->signal_connect('toggled' => \&toggle,"Radio two"); 69 $menu_edit->append($menu_radio_two); 70 71 #_________ 72 #add a separator 73 $menu_edit->append(Gtk2::SeparatorMenuItem->new()); 74 75 #_________ 76 #add an Image Menu Item using an external image 77 my $menu_item_image = Gtk2::ImageMenuItem->new ('Image Menu Item'); 78 my $img = Gtk2::Image->new_from_file('./pix/1.png'); 79 $menu_item_image->signal_connect('activate' => sub { print "selected the Image Menu Item\n"}); 80 #connet to the activate signal to catch when this item is selected 81 $menu_item_image->set_image($img); 82 83 $menu_edit->append($menu_item_image); 84 #==================================== 85 86 #create a menu bar with two menu items, one will have $menu_edit 87 #as a submenu 88 my $menu_bar = Gtk2::MenuBar->new; 89 90 #_________ 91 #add a menu item 92 my $menu_item_edit= Gtk2::MenuItem->new('_Edit'); 93 #set its sub menu 94 $menu_item_edit->set_submenu ($menu_edit); 95 96 $menu_bar->append($menu_item_edit); 97 98 #_________ 99 #add a menu item 100 my $menu_item_help = Gtk2::MenuItem->new('_Help'); 101 $menu_item_help->set_sensitive(FALSE); 102 #push it off to the right 103 $menu_item_help->set_right_justified(TRUE); 104 105 $menu_bar->append($menu_item_help); 106 107 $vbox->pack_start($menu_bar,FALSE,FALSE,0); 108 109 #==================================== 110 #add an event box to catch the right clicks 111 my $eventbox = Gtk2::EventBox->new(); 112 113 $eventbox->signal_connect('button-release-event' => sub { 114 115 my ($widget,$event) = @_; 116 my $button_nr = $event->button; 117 #make sure it was the right mouse button 118 ($button_nr == 3)&&($menu_edit->popup(undef,undef,undef,undef,0,0)); 119 120 }); 121 122 $vbox->pack_start($eventbox,TRUE,TRUE,0); 123 $vbox->show_all(); 124 return $vbox; 125 } 126 127 sub toggle { 128 129 my ($menu_item,$text) = @_; 130 my $val = $menu_item->get_active; 131 ($val)&&(print "$text active\n"); 132 ($val)||(print "$text not active\n"); 133 }
A Gtk2::MenuShell
contains menu items. In our program we make use of the various types available. The Gtk2::MenuShell
has various methods available to insert the menu items in destined places. Consult the man page to discover the one that best fits your needs. In our program we make use of the 'append'
method.
The demo program uses the two available subclasses of Gtk2::MenuShell
. They are Gtk2::Menu
and Gtk2::MenuBar
. We add menu items to the Gtk2::MenuBar
, and then we use the Gtk2::MenuItem
's 'set_submenu'
to "attach" a Gtk2::Menu
to that Gtk2::MenuItem
. This will cause the Gtk2::Menu
with all its menu items to 'popup'
as soon as we click on the menu to which the Gtk2::Menu
was "attached".
By using the 'set_submenu'
method you can build the desired structure of your menus.
To be notified when a menu item is selected, we connect to its 'activate'
signal.
To be notified when the state of a Gtk2::CheckMenuItem
and Gtk2::RadioMenuItem
changed, we connect to its 'toggled'
signal.
When you want a menu item to appear on the right hand side of the Gtk2::MenuBar
make use of the Gtk2::MenuItem
's 'set_right_justified'
method.
We also use the created Gtk2::Menu
to be a "popup" menu, by making use of its 'popup'
method. We filter for the right mouse button, to simulate the typical use op a popup menu.
When you need to create and manage large menu structures, make use of |