Customising the Standard Menu Bar
By default, a PyGUI application comes with a standard set of menus
containing all the commands that the PyGUI framework itself knows about
- Open, Close, Save, Cut, Copy, Paste and so forth. It's likely that
you won't use all of these commands in your application, will want to
omit some of them. It's also likely that you will want to add new
commands of your own. PyGUI offers a variety of mechanisms to do these
things in a platform-independent way.
Choosing standard menu items
The basic_menus() function from the StdMenus
module provides a starting point for building your application's main
menu bar. Without any parameters, it returns a list of menus containing
all of the standard commands, arranged according to platform
conventions.
If you want to be more selective, there are a
couple of ways to go about it. One is to start with all the standard
items and take away the ones you don't want using the exclude
parameter, which takes a sequence or set of command names. The StdMenus
module exports a number of predefined command sets to make this easier.
For example, the following creates a menu bar containing all the
standard commands except those having to do with files or printing.
from GUI.StdMenus import basic_menus, file_cmds, print_cmds
menus = basic_menus(exclude = file_cmds + print_cmds)
The menu bar is installed by assigning it to the menus property of the application.
app = MyApplication()
app.menus = menus
The other way is to start with a minimal set of commands and add the extra ones that you want using the include parameter. When you specify a value for include, the menu bar will include only those items, plus the fundamental_cmds and edit_cmds,
which are considered essential for most applications. The following
creates a menu bar containing only the file-related commands and the
"Preferences" command in addition to the essential ones.
menus = basic_menus(include = file_cmds + prefs_cmds)
You can use both include and exclude
together; this is the only way to omit items from the essential set.
The following includes all of the file-related commands except
"Revert", and also omits the "Redo" command, which would otherwise be
implicitly included because it is part of the edit_cmds set.
menus = basic_menus(include = file_cmds, exclude = ['revert_cmd', 'redo_cmd'])
Note,
however, that it is generally a bad idea to exclude items from the
essential set. On some platforms, for example, the editing commands
need to be present in the menus in order for their keyboard equivalents
to work in dialogs.
Modifying standard menu items
Sometimes
you will want to give different titles or keyboard equivalents to
standard menu commands. For example, in a game you might want the New,
Open and Save commands to be called "New Game", "Load Game" and "Save
Game", and give "Load Game" a keyboard equivalent of "L" instead of "O".
You can do this easily using the substitutions parameter to basic_menus(). It takes a dictionary whose keys are command names and values are replacement menu item strings. For example:
menus = basic_menus(substitutions = {
'new_cmd': "New Game",
'open_cmd': "Load Game.../L",
'save_cmd': "Save Game",
'save_as_cmd': "Save Game As..."})
Each
replacement can override just the title, just the keyboard equivalent,
or both. In the above example, the keyboard equivalent of open_cmd is overridden, but the other commands are left with their standard equivalents.Adding menus
The simplest way to add new commands is to create one or more extra menus containing your
commands, and add them to the end of the application's menu bar. Here's
an example of how to do this.
menus = basic_menus()
my_menu = Menu("Widget", [("Swizzle", 'swiz_cmd'), ("Defibrillate", 'defib_cmd')])
menus.append(my_menu)
app.menus = menus
Note that the new menu is added to the menu list before assigning the menu list to the application's menus property. This is important, to ensure that the menu bar is updated properly.
Adding commands to standard menus
Adding your own menus is all well and good, but you may want more
control than that. For example, if you have some editing-related
commands, you might want to add them to the Edit menu instead of
putting them in a menu of their own.
The problem with this is finding the right menu to add them to. PyGUI
tries to make as few assumptions as possible about the layout of the
standard menus, and if you want your application to be portable, you
should do the same. So you shouldn't assume, for example, that the Edit
menu is the second menu in the menu bar. (On the Mac, it's not!) You
shouldn't even assume that there will be an Edit menu at all.
Rather than a particular menu, it's better to think in terms of putting
your commands near existing commands. PyGUI helps you out here by means
of the MenuList class. A
MenuList is just like an ordinary list, except that it also has a
method that will take an internal command name and give you the menu
which contains that command. So we can find the menu containing, say,
the 'copy_cmd' command,
and be fairly sure that it's the Edit menu, or whatever passes for it,
on the platform we're running on. Once we've found the menu, we can use
its append or extend methods to add our commands to it.
The basic_menus() function returns a MenuList, so here's how we can add some commands to the Edit menu:
menus = basic_menus()
edit_menu = menus.menu_with_command('copy_cmd')
edit_menu.extend(["-", ("Biggify", 'enlarge_cmd'), ("Smallify", 'reduce_cmd')])
app.menus = menus
Future plans
One further thing you might want to do is insert commands in the
middle of a menu (to get them even closer to an existing command). This is
not currently supported, but is planned for a future version.
---