Prev

Up

Next

wxGlade tutorial - Menu

(Contributed by Chris Lale, chrislale AT users DOT berlios DOT de)

Table of Contents:

Create the application in wxglade

Run wxglade. Open the simple project simple-glade.wxg that you created in "first steps" (WxGladeFirstSteps). The project consists of one empty frame. Set the title to "menu-glade" and save it as menu-glade.wxg. In the main (toolbox) window

The Tree shows that the application contains one frame (window)and a sizer to added automatically by wxGlade.

About the wx.Menu class

A menu is a popup (or pull down) list of items, one of which may be selected before the menu goes away (clicking elsewhere dismisses the menu). Menus may be used to construct either menu bars or popup menus.

Look for wxWindow's methods in

and

Construct a menubar object

Look up wx.Menu's __init__() method, or constructor. You should find that __init__() has two string parameters:

In the wxGlade Tree window, double-click on frame_1(MyFrame). This opens the Design window and the Properties window for frame_1. The wx.Menu __init__() method is set by the Has MenuBar option in the Widget tab of the Properties window:

This adds these lines to MyFrame's __init()__ method:

   1         # Menu Bar
   2         self.frame_1_menubar = wx.MenuBar()
   3         self.SetMenuBar(self.frame_1_menubar)
   4         # Menu Bar end

The code constructs a new wx.Menu menubar object (frame_1_menubar), and tells the frame to show the menubar with the wx.Frame method SetMenuBar().

Add menu items to the menubar

The menubar is just a container widget - there is nothing to see until you have added some menu items. First, add "File", "Edit" and "Help" items:

This brings up the Menu editor. Add the items and give them labels:

Check the result:

Add menu items to the File menu

Now add some items to the File menu:

Use the "Down" button to move the item directly below "&File". Use the ">" button to demote the item one level. In the same way, add items for "&Save" and "&Quit:

Now highlight "&Save" and insert a separator above "&Quit"

Check the result:

Generate the Python code. In the Tree window, select Application.

In the Properties window, enter a new filename for the python file.

Click on

Look at the code in a text editor or Idle:

   1         # Menu Bar
   2         self.frame_1_menubar = wx.MenuBar()
   3         self.SetMenuBar(self.frame_1_menubar)
   4         wxglade_tmp_menu = wx.Menu()
   5         wxglade_tmp_menu.Append(wx.NewId(), "&Open", "", wx.ITEM_NORMAL)
   6         wxglade_tmp_menu.Append(wx.NewId(), "&Save", "", wx.ITEM_NORMAL)
   7         wxglade_tmp_menu.AppendSeparator()
   8         wxglade_tmp_menu.Append(wx.NewId(), "&Quit", "", wx.ITEM_NORMAL)
   9         self.frame_1_menubar.Append(wxglade_tmp_menu, "&File")
  10         wxglade_tmp_menu = wx.Menu()
  11         self.frame_1_menubar.Append(wxglade_tmp_menu, "&Edit")
  12         wxglade_tmp_menu = wx.Menu()
  13         self.frame_1_menubar.Append(wxglade_tmp_menu, "&Help")
  14         # Menu Bar end

Add a keyboard accelerator to the Quit menu item

The item string for the normal menu items (not submenus or separators) may include the accelerator which can be used to activate the menu item from keyboard. The accelerator string follows the item label and is separated from it by a TAB character ('\t'). Its general syntax is any combination of "CTRL", "ALT" and "SHIFT" strings (case doesn't matter) separated by either '-' or '+' characters and followed by the accelerator key itself.

Use the menu editor to add the key combination ctrl-q to the Quit menu item:

Make the Quit menu item close the application

Use wxGlade to create an event handler that reponds to "Quit" being selected. In wxGlade, edit the entry for "&Quit" and add an event handler called OnQuit:

Generate the Python code. Look at the code in a text editor or Idle. wxGlade has added a new OnQuit method to the MyFrame class:

   1     def OnQuit(self, event): # wxGlade: MyFrame.<event_handler>
   2         print "Event handler `OnQuit` not implemented"
   3         event.Skip()

Also, a new method is added to MyFrame's __init__() method to bind the "Quit" menu item to the OnQuit() method:

   1         self.Bind(wx.EVT_MENU, self.OnQuit, self.quit)

If you run menu-glade.py from a terminal window and click on

"Event handler OnQuit not implemented" is printed to standard output (the terminal window).Replace

   1         print "Event handler `OnQuit` not implemented"

with

   1         self.Close()

Save the file and run it. Now, clicking on

invokes the Close() method which is inherited by MyFrame from wx.Window.

Add an icon to the Quit item

Make sure that stock_quit.png exists in the working directory. In Linux systems with Gtk, you can find it somewhere like /usr/share/icons/hicolor/16x16/stock/generic/stock_exit.png.

You must add the SetBitmap() method to the code manually. To do this, you must first create the "File" menu as a named wx.Menu object, and the "Quit" menu item as a named wx.MenuItem object.

In wxGlade, edit the entry for "&File" and add the Name file:

Do the same for "&quit":

Generate the Python code. Look at the code in a text editor or Idle:

   1         # Menu Bar
   2         self.frame_1_menubar = wx.MenuBar()
   3         self.SetMenuBar(self.frame_1_menubar)
   4         self.file = wx.Menu()
   5         self.file.Append(wx.NewId(), "&Open", "", wx.ITEM_NORMAL)
   6         self.file.Append(wx.NewId(), "&Save", "", wx.ITEM_NORMAL)
   7         self.file.AppendSeparator()
   8         self.quit = wx.MenuItem(self.file, wx.NewId(), "&Quit\tCtrl+Q", "", wx.ITEM_NORMAL)
   9         self.file.AppendItem(self.quit)
  10         self.frame_1_menubar.Append(self.file, "&File")
  11         wxglade_tmp_menu = wx.Menu()
  12         self.frame_1_menubar.Append(wxglade_tmp_menu, "&Edit")
  13         wxglade_tmp_menu = wx.Menu()
  14         self.frame_1_menubar.Append(wxglade_tmp_menu, "&Help")
  15         # Menu Bar end

Notice how

   1         wxglade_tmp_menu = wx.Menu()
   2         ...
   3         self.frame_1_menubar.Append(wxglade_tmp_menu, "&File")

has become

   1         self.file = wx.Menu()
   2         ...
   3         self.frame_1_menubar.Append(self.file, "&File")

and

   1         wxglade_tmp_menu.Append(wx.NewId(), "&Quit\tCtrl+Q", "", wx.ITEM_NORMAL)

has become

   1         self.quit = wx.MenuItem(self.file, wx.NewId(), "&Quit\tCtrl+Q", "", wx.ITEM_NORMAL)
   2         self.file.AppendItem(self.quit)

Now add the stock_exit.png image using the SetBitMap() method. wxPython can only put bitmaps into menus. You must convert the .png file to a bitmap using ConvertToBitmap(). Insert this line just after the line that creates the "quit" menuitem object:

   1         self.quit.SetBitmap(wx.Image('stock_exit.png',
   2                                 wx.BITMAP_TYPE_PNG).ConvertToBitmap())

The Menu Bar section now looks like this.

   1         # Menu Bar
   2         self.frame_1_menubar = wx.MenuBar()
   3         self.SetMenuBar(self.frame_1_menubar)
   4         self.file = wx.Menu()
   5         self.file.Append(wx.NewId(), "&Open", "", wx.ITEM_NORMAL)
   6         self.file.Append(wx.NewId(), "&Save", "", wx.ITEM_NORMAL)
   7         self.file.AppendSeparator()
   8         self.quit = wx.MenuItem(self.file, wx.NewId(), "&Quit\tCtrl+Q", "", wx.ITEM_NORMAL)
   9         self.quit.SetBitmap(wx.Image('stock_exit.png',
  10                                 wx.BITMAP_TYPE_PNG).ConvertToBitmap())
  11         self.file.AppendItem(self.quit)
  12         self.frame_1_menubar.Append(self.file, "&File")
  13         wxglade_tmp_menu = wx.Menu()
  14         self.frame_1_menubar.Append(wxglade_tmp_menu, "&Edit")
  15         wxglade_tmp_menu = wx.Menu()
  16         self.frame_1_menubar.Append(wxglade_tmp_menu, "&Help")
  17         # Menu Bar end

Save menu-glade.py and run it. Check that you can see the icon in the "Quit" menu item.

You may find that the SetBitmap() line is deleted next time you regenerate menu-glade.py from wxGlade. For this reason, add icons to menus only after you have finished building the complete GUI.


Appendix: The complete code

   1 #!/usr/bin/env python
   2 # -*- coding: ISO-8859-1 -*-
   3 # generated by wxGlade 0.4.1 on Tue Mar 28 19:05:38 2006
   4 
   5 import wx
   6 
   7 class MyFrame(wx.Frame):
   8     def __init__(self, *args, **kwds):
   9         # begin wxGlade: MyFrame.__init__
  10         kwds["style"] = wx.DEFAULT_FRAME_STYLE
  11         wx.Frame.__init__(self, *args, **kwds)
  12 
  13         # Menu Bar
  14         self.frame_1_menubar = wx.MenuBar()
  15         self.SetMenuBar(self.frame_1_menubar)
  16         self.file = wx.Menu()
  17         self.file.Append(wx.NewId(), "&Open", "", wx.ITEM_NORMAL)
  18         self.file.Append(wx.NewId(), "&Save", "", wx.ITEM_NORMAL)
  19         self.file.AppendSeparator()
  20         self.quit = wx.MenuItem(self.file, wx.NewId(), "&Quit\tCtrl+Q", "", wx.ITEM_NORMAL)
  21         self.quit.SetBitmap(wx.Image('stock_exit.png',
  22                                 wx.BITMAP_TYPE_PNG).ConvertToBitmap())
  23         self.file.AppendItem(self.quit)
  24         self.frame_1_menubar.Append(self.file, "&File")
  25         wxglade_tmp_menu = wx.Menu()
  26         self.frame_1_menubar.Append(wxglade_tmp_menu, "&Edit")
  27         wxglade_tmp_menu = wx.Menu()
  28         self.frame_1_menubar.Append(wxglade_tmp_menu, "&Help")
  29         # Menu Bar end
  30 
  31         self.__set_properties()
  32         self.__do_layout()
  33 
  34         self.Bind(wx.EVT_MENU, self.OnQuit, self.quit)
  35         # end wxGlade
  36 
  37     def __set_properties(self):
  38         # begin wxGlade: MyFrame.__set_properties
  39         self.SetTitle("menu-glade")
  40         self.SetSize((343, 510))
  41         # end wxGlade
  42 
  43     def __do_layout(self):
  44         # begin wxGlade: MyFrame.__do_layout
  45         sizer_1 = wx.BoxSizer(wx.VERTICAL)
  46         self.SetAutoLayout(True)
  47         self.SetSizer(sizer_1)
  48         self.Layout()
  49         # end wxGlade
  50 
  51     def OnQuit(self, event): # wxGlade: MyFrame.<event_handler>
  52         self.Close()
  53         event.Skip()
  54 
  55 # end of class MyFrame
  56 
  57 
  58 class MyApp(wx.App):
  59     def OnInit(self):
  60         wx.InitAllImageHandlers()
  61         frame_1 = MyFrame(None, -1, "")
  62         self.SetTopWindow(frame_1)
  63         frame_1.Show()
  64         return 1
  65 
  66 # end of class MyApp
  67 
  68 if __name__ == "__main__":
  69     app = MyApp(0)
  70     app.MainLoop()

WxGladeWxMenu (last edited 2013-10-17 21:30:23 by mail)

NOTE: To edit pages in this wiki you must be a member of the TrustedEditorsGroup.