14.2. Manual Menu Example

That should about do it. Let's take a look at the menu.py example program to help clarify the concepts. Figure 14.1 illustrates the program display:

Figure 14.1 Menu Example

The menu.py program source code is:
 
    1   #!/usr/bin/env python
    2   
    3   # example menu.py
    4   
    5   import gtk
    6   import GDK
    7   
    8   class MenuExample:
    9       def __init__(self):
   10           # create a new window
   11           window = gtk.GtkWindow(gtk.WINDOW_TOPLEVEL)
   12           window.set_usize(200, 100)
   13           window.set_title("GTK Menu Test")
   14           window.connect("delete_event", gtk.mainquit)
   15   
   16           # Init the menu-widget, and remember -- never
   17           # show() the menu widget!! 
   18           # This is the menu that holds the menu items, the one that
   19           # will pop up when you click on the "Root Menu" in the app
   20           menu = gtk.GtkMenu()
   21   
   22           # Next we make a little loop that makes three menu-entries for
   23           # "test-menu".  Notice the call to gtk_menu_append.  Here we are
   24           # adding a list of menu items to our menu.  Normally, we'd also
   25           # catch the "clicked" signal on each of the menu items and setup a
   26           # callback for it, but it's omitted here to save space.
   27           for i in range(3):
   28               # Copy the names to the buf.
   29               buf = "Test-undermenu - %d" % i
   30   
   31               # Create a new menu-item with a name...
   32               menu_items = gtk.GtkMenuItem(buf)
   33   
   34               # ...and add it to the menu.
   35               menu.append(menu_items)
   36   
   37               # Do something interesting when the menuitem is selected
   38               menu_items.connect("activate", self.menuitem_response, buf)
   39   
   40               # Show the widget
   41               menu_items.show()
   42   
   43           # This is the root menu, and will be the label
   44           # displayed on the menu bar.  There won't be a signal handler attached,
   45           # as it only pops up the rest of the menu when pressed.
   46           root_menu = gtk.GtkMenuItem("Root Menu")
   47   
   48           root_menu.show()
   49   
   50           # Now we specify that we want our newly created "menu" to be the
   51           # menu for the "root menu"
   52           root_menu.set_submenu(menu)
   53   
   54           # A vbox to put a menu and a button in:
   55           vbox = gtk.GtkVBox(gtk.FALSE, 0)
   56           window.add(vbox)
   57           vbox.show()
   58   
   59           # Create a menu-bar to hold the menus and add it to our main window
   60           menu_bar = gtk.GtkMenuBar()
   61           vbox.pack_start(menu_bar, gtk.FALSE, gtk.FALSE, 2)
   62           menu_bar.show()
   63   
   64           # Create a button to which to attach menu as a popup
   65           button = gtk.GtkButton("press me")
   66           button.connect_object("event", self.button_press, menu)
   67           vbox.pack_end(button, gtk.TRUE, gtk.TRUE, 2)
   68           button.show()
   69   
   70           # And finally we append the menu-item to the menu-bar -- this is the
   71           # "root" menu-item I have been raving about =)
   72           menu_bar.append (root_menu)
   73   
   74           # always display the window as the last step so it all splashes on
   75           # the screen at once.
   76           window.show()
   77   
   78       # Respond to a button-press by posting a menu passed in as widget.
   79       #
   80       # Note that the "widget" argument is the menu being posted, NOT
   81       # the button that was pressed.
   82       def button_press(self, widget, event):
   83           if event.type == GDK.BUTTON_PRESS:
   84               widget.popup(None, None, None, event.button, event.time)
   85               # Tell calling code that we have handled this event the buck   86               # stops here.
   87               return gtk.TRUE
   88           # Tell calling code that we have not handled this event pass it on.
   89           return gtk.FALSE
   90   
   91       # Print a string when a menu item is selected
   92       def menuitem_response(self, widget, string):
   93           print "%s" % string
   94   
   95   def main():
   96       gtk.mainloop()
   97       return 0
   98   
   99   if __name__ == "__main__":
  100       MenuExample()
  101       main()

You may also set a menu item to be insensitive and, using an accelerator table, bind keys to menu callbacks.