Python GUI Programming Cookbook
上QQ阅读APP看书,第一时间看更新

Creating menu bars

In this recipe, we will add a menu bar to our main window, add menus to the menu bar, and then add menu items to the menus.

Getting ready

We will start by learning the techniques of how to add a menu bar, several menus and a few menu items to show the principle of how to do it. Clicking on a menu item will have no effect. Next, we will add functionality to the menu items, for example, closing the main window when clicking the Exit menu item and displaying a Help | About dialog.

We are continuing to extend the GUI we created in the current and previous chapter.

How to do it...

First, we have to import the Menu class from tkinter. Add the following line of code to the top of the Python module, where the import statements live:

from tkinter import Menu

Next, we will create the menu bar. Add the following code towards the bottom of the module, just above where we create the main event loop:

menuBar = Menu(win)                      # 1
win.config(menu=menuBar)

Now we add a menu to the bar and also assign a menu item to the menu.

fileMenu = Menu(menuBar)                 # 2
fileMenu.add_command(label="New")
menuBar.add_cascade(label="File", menu=fileMenu)

Running this code adds a menu bar, with a menu, which has a menu item.

Next, we add a second menu item to the first menu we added to the menu bar.

fileMenu.add_command(label="New")
fileMenu.add_command(label="Exit")        # 3
menuBar.add_cascade(label="File", menu=fileMenu)

We can add a separator line between the MenuItems by adding the following line of code (# 4) in between the existing MenuItems.

fileMenu.add_command(label="New")
fileMenu.add_separator()               # 4
fileMenu.add_command(label="Exit")

By passing in the property tearoff to the constructor of the menu, we can remove the first dashed line that, by default, appears above the first MenuItem in a menu.

# Add menu items
fileMenu = Menu(menuBar, tearoff=0)      # 5

We will add a second menu, which will be horizontally placed to the right of the first menu. We will give it one MenuItem, which we name About, and, in order for this to work, we have to add this second menu to the MenuBar.

File and Help | About are very common Windows GUI layouts that we are all familiar with, and we can create those same menus using Python and tkinter.

The order of creation and the naming of menu, menu item, and menu bar might at first be a little bit confusing, but, once we get used to how tkinter requires us to code it, this actually becomes fun.

helpMenu = Menu(menuBar, tearoff=0)            # 6
helpMenu.add_command(label="About")
menuBar.add_cascade(label="Help", menu=helpMenu)

At this point, our GUI has a MenuBar and two menus that contain some MenuItems. Clicking on them does not do much, until we add some commands. That's what we will do next. Add the following code above the creation of the MenuBar:

def _quit():         # 7
    win.quit()
    win.destroy()
    exit()

Next, we bind the File | Exit MenuItem to this function by adding the following command to the MenuItem:

fileMenu.add_command(label="Exit", command=_quit)    # 8

Now, when we click the Exit MenuItem, our application will indeed exit.

How it works...

In comment # 1, we are calling the tkinter constructor of the menu and assigning the menu to our main GUI window. We save a reference in the instance variable named menuBar and, in the following line of code, we use this instance to configure our GUI to use menuBar as our menu.

Comment # 2 shows how we first add a MenuItem and then create a menu. This seems to be unintuitive, but this is how tkinter works. The add_cascade() method aligns the MenuItems one below the other, in a vertical layout.

Comment # 3 shows how to add a second MenuItem to the menu.

In comment # 4, we are adding a separator line between the two MenuItems. This is usually used to group related MenuItems and separate them from less related items (hence the name).

Comment # 5 disables the tearoff dashed line to make our menu look much better.

Note

Without disabling this default feature, the user can "tear off" the menu from the main window. I find this capability to be of little value. Feel free to play around with it by double-clicking the dashed line (before disabling this feature).

If you are using a Mac, this feature might not be enabled, so you do not have to worry about it at all.

Comment # 6 shows you how to add a second menu to the MenuBar. We can keep on adding menus by using this technique.

Comment # 7 creates a function to quit our GUI application cleanly. This is the recommended Pythonic way to end the main event loop.

In # 8 we bind the function we created in # 7 to the MenuItem, using the tkinter command property. Whenever we want our MenuItems to actually do something, we have to bind each of them to a function.

Note

We are using a recommended Python naming convention by preceding our quit function with one single underscore, to indicate that this is a private function not to be called by clients of our code.

There's more…

We will add the Help | About functionality in the next chapter, which introduces message boxes and much more.