Skip to main content

Wrapper classes for easy implementation of Tkinter menus.

This package was created to simplify the process of implementing menus in Tkinter windows. This was accomplished by defining functional "building block" classes which can be assembled together to create the user interface. Each of these classes provides the methods and properties needed to accomplish the assembly task. The design goal was to make this process as easy and intuitive as possible.

As a quick example, the following script will construct a Tkinter window and display a top menu bar that contains a single menu entry labeled File. This entry is a drop-down menu, and it has a selection item labeled Exit. Clicking on this item will call the on_exit( ) event handler, which closes the window and exits the program.

from tkinter import Tk
from menus import MainMenu

root = Tk()

def on_exit():
    root.destroy()

# Create and Populate the Top Menu Bar
menu_bar = MainMenu(root)
file_menu = menu_bar.add_menu('File')
file_menu.add_item('Exit', on_exit)

root.mainloop()

Overview

This package provides the following class definitions :

  • MainMenu - A class that displays a menu bar across the top of a window.
  • Menu - A class used to represent a selection menu.
  • MenuItem - A class used to represent a selection item in a Menu.
  • EntryType - An enumerated dataclass of the available MenuItem entry types.
  • ConfigInfo - A dataclass that provides MenuItem configuration information.
  • MenuButton - A class used to represent a drop-down selection menu button.
  • ContextMenu - A class used to represent a pop-up context menu.

The MainMenu, Menu, and MenuItem classes are the three "building blocks" used to construct the user interface for applications.

Consider the previous section's example script with the following changes :

  1. The import statement now includes the Menu, and the MenuItem classes.
  2. The File menu is first created and then added to the top menu bar.
  3. The Exit selection item is first created and then added to the File menu.
from tkinter import Tk
from menus import MainMenu, Menu, MenuItem

root = Tk()

def on_exit():
    root.destroy()

# Create and Populate the Top Menu Bar
menu_bar = MainMenu(root)
file_menu = Menu('File')
menu_bar.add(file_menu)
exit_item = MenuItem('Exit', on_exit)
file_menu.add(exit_item)

root.mainloop()

Both scripts are functionally equivalent, but the second version shows the individual classes being created and then assembled to construct the user interface. The reader can refer to The Zen of Python to decide if either one of these two scripts is the more Pythonic than the other.

Referring back to the original example script, consider these two changes to the Exit selection item :

  1. The Exit selection item's label string has been changed to 'E&xit'
  2. The Exit selection item's shortcut property has been assigned a key character value of 'w'
from tkinter import Tk
from menus import MainMenu

root = Tk()

def on_exit():
    root.destroy()

# Create and Populate the Top Menu Bar
menu_bar = MainMenu(root)
file_menu = menu_bar.add_menu('File')
file_menu.add_item('E&xit', on_exit).shortcut = 'w'

root.mainloop()

The Windows and Linux platforms support the Alt+Key technique for navigating the top menu bar and its entries. The active key value for each entry appears as an underlined character in that entry's label. By default, the first character in the entry's label is the active key value. In this example, the top menu bar displays a File label. When the & symbol appears in the label string, the next character in the label will be designated as the active key value for that entry. The & symbol is not part of the displayed label. In this example, the 'E&xit' string denotes that the x character is the active key value for this entry, and the label is displayed as Exit on the screen.

The shortcut property allows a selection item to have a Control+Key ( Command+key ) keyboard shortcut assigned to it. This is consistent with commonly used keyboard shortcuts such as the Ctrl+C ( ⌘C ) shortcut for a Copy, or the Ctrl+V ( ⌘V ) shortcut for a Paste. In this example, assigning the 'w' character to the shortcut property creates a keyboard shortcut of Ctrl+W ( ⌘W ) for the Exit selection item. The shortcut's name is displayed next to the label on the screen. The MenuItem class also has a set_custom_shortcut( ) method which can be used to assign other kinds of keyboard shortcuts, such as using a Function Key as a shortcut. The reader should refer to the Tkinter documentation for information on keyboard events.

The reader may wonder why the 'q' character wasn't chosen for the Exit shortcut. The Ctrl+Q shortcut is commonly used to exit a program, and it certainly can be used on either a Windows or a Linux platform. However, the ⌘Q shortcut is reserved for the system-level Quit command on macOS platforms. For the ⌘Q shortcut to actually call the on_exit( ) event handler, the macOS user must override the system by adding the following statement :

root.createcommand('tk::mac::Quit', on_exit)

A menu entry can also display an icon image. Assuming there is an image_folder that contains an icon image file named exit.png, an icon image can be added to the Exit selection item by making the following changes to the previous example :

  1. Import the PhotoImage class from tkinter
  2. Create an exit_icon PhotoImage from the image_folder/exit.png image file
  3. Add the exit_icon PhotoImage to the Exit selection item's argument list
from tkinter import Tk, PhotoImage
from menus import MainMenu

root = Tk()

def on_exit():
    root.destroy()

# Create and Populate the Top Menu Bar
menu_bar = MainMenu(root)
file_menu = menu_bar.add_menu('File')

exit_icon = PhotoImage(file='image_folder/exit.png')
file_menu.add_item('E&xit', on_exit, exit_icon).shortcut = 'w'

root.mainloop()

An application's top menu bar typically contains several drop-down menu entries. In this next example, four entries ( File, Edit, View, and Help ) are added to the top menu bar. The begin_update( ) method should be called prior to adding multiple entries to the MainMenu class. Calling this method causes all the added entries to be placed into a queue, and it prevents multiple screen updates from occurring during this process. When all the entries have been added, the end_update( ) method is called to process all the queued entries and to allow those entries to be displayed on the screen. Use of the begin_update( ) ... end_update( ) pair is recommended on all platforms, and it is required on the macOS platform to ensure the correct behavior of the top menu bar.

# Create and Populate the Top Menu Bar
menu_bar = MainMenu(root)
menu_bar.begin_update()
file_menu = menu_bar.add_menu('File')
edit_menu = menu_bar.add_menu('Edit')
view_menu = menu_bar.add_menu('View')
help_menu = menu_bar.add_menu('Help')
menu_bar.end_update()

...

Continuing this theme, a typical File drop-down menu will also have several selection items, such as Open, Save, and Exit. The add_separator( ) method displays a horizontal line between the Save and Exit selection items. Once again, the begin_update( ) ... end_update( ) pair should be used when adding multiple entries to an instance of the Menu class.

def on_open():
    print('File_Menu - Open')

def on_save():
    print('File_Menu - Save')

open_icon = PhotoImage(file='image_folder/open.png')
save_icon = PhotoImage(file='image_folder/save.png')
exit_icon = PhotoImage(file='image_folder/exit.png')

file_menu.begin_update()
file_menu.add_item('Open', on_open, open_icon).shortcut = 'o'
file_menu.add_item('Save', on_save, save_icon).shortcut = 's'
file_menu.add_separator()
file_menu.add_item('E&xit', on_exit, exit_icon).shortcut = 'w'
file_menu.end_update()

...

In this next code snippet, the Edit drop-down menu has the Cut, Copy, and Paste selection items. Here the & symbol appears in the Cu&t label string, and it is used to make that entry's active key value = 't'.

def on_cut():
    print('Edit_Menu - Cut')

def on_copy():
    print('Edit_Menu - Copy')

def on_paste():
    print('Edit_Menu - Paste')

edit_menu.begin_update()
edit_menu.add_item('Cu&t', on_cut).shortcut = 'x'
edit_menu.add_item('Copy', on_copy).shortcut = 'c'
edit_menu.add_item('Paste', on_paste).shortcut = 'v'
edit_menu.end_update()

...

The View drop-down menu has a Zoom menu entry, which in turn, has have three different zoom options. These three selection items are configured to behave like Tkinter Radiobutton widgets. First, the import statements from the previous example need to be updated to the following :

from tkinter import Tk, PhotoImage, IntVar
from menus import MainMenu, EntryType, ConfigInfo

Next, each selection item in the Zoom menu must be configured as a 'Radiobutton' entry. The EntryType and the ConfigInfo dataclasses are used to perform that task. The EntryType defines the behavior of the entry, and it can be one of three options : STANDARD( default ), CHECKBUTTON, or RADIOBUTTON. Just like Radiobuttons, the Tkinter IntVar class is used to provide communication between the entries, and each entry must have a unique id value. The ConfigInfo dataclass is used to provide the configuration information when creating each of the three selection items. In this next code section, the three different zoom options are created and added to the Zoom menu entry in the View drop-down menu :

zoom_variable = IntVar(value=100)

def on_zoom():
    print(f'View_Menu - Zoom {zoom_variable.get()}%')

zoom_menu = view_menu.add_menu('Zoom')
zoom_menu.begin_update()
for value in (100, 200, 400):
    label = f'&{value}%'
    config = ConfigInfo(EntryType.RADIOBUTTON, zoom_variable, value)
    zoom_menu.add_item(label, on_zoom, config=config)
zoom_menu.end_update()

...

Finally, the Help drop-down menu has a single selection item labeled About, which has been assigned 'Ctrl+Shift+A' as its custom keyboard shortcut.

def on_about():
    print('Help_Menu - About')

about = help_menu.add_item('About', on_about)
about.set_custom_shortcut('<Control-Shift-A>', 'Ctrl+Shift+A')

root.mainloop()

The MenuButton is essentially a single entry menu bar that can be positioned anywhere in the application window. The MenuButton's text and optional image are always visible on the screen. Its drop-down menu, the menu property, is displayed when the MenuButton is clicked. This is an example using the MenuButton :

from tkinter import Tk
from menus import MenuButton

root = Tk()
selections = MenuButton(root, 'Selections', 20)
selections.grid(padx=40, pady=40)
selections.menu.begin_update()
for i in range(1, 5):
    def on_select(index=i):
        print(f'Selection Number {index}')
    selections.menu.add_item(f'Selection #{i}', on_select)
selections.menu.end_update()
root.mainloop()

The ContextMenu is a pop-up menu that can be displayed at a specified screen location. A ContextMenu is not visible until it is invoked by some action, usually a right-button mouse click. In this next example, a ContextMenu is created and then associated with a Label widget :

from tkinter import Tk, Label
from menus import ContextMenu

root = Tk()

def on_context_event():
    print('Context Menu Event')

context_menu = ContextMenu()
context_menu.add_item('Copy', on_context_event)
context_menu.add_item('Save As ...', on_context_event)
context_menu.add_item('Delete Text', on_context_event)

label = Label(root, text=' ContextMenu Example  ', relief='groove')
label.grid(padx=40, pady=40)

def on_right_button(e):  # Display the ContextMenu at the mouse position
    position = (label.winfo_rootx() + e.x, label.winfo_rooty() + e.y)
    context_menu.display(position)

label.bind('<Button-3>', on_right_button)  # use '<Button-2>' on macOS
root.mainloop()

Documentation

Full documentation for all the classes contained in this package, as well as usage examples, are available at the package's GitHub repository: https://github.com/johnbolk/easy-menus

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

easy_menus-1.3.6.tar.gz (13.6 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

easy_menus-1.3.6-py3-none-any.whl (14.5 kB view details)

Uploaded Python 3

File details

Details for the file easy_menus-1.3.6.tar.gz.

File metadata

  • Download URL: easy_menus-1.3.6.tar.gz
  • Upload date:
  • Size: 13.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/7.0.0 CPython/3.10.8

File hashes

Hashes for easy_menus-1.3.6.tar.gz
Algorithm Hash digest
SHA256 496aa0850f60983eb735388b4e2ce72d2edbe5fe989991b60755292928dc0e1e
MD5 e1c8cfdd6f5a213a45e5e8a3630b40c7
BLAKE2b-256 577e7ab1fb3a4a9efa9c11fd8c701d4ec17130a68653b896751da5a17e5b03ac

See more details on using hashes here.

File details

Details for the file easy_menus-1.3.6-py3-none-any.whl.

File metadata

  • Download URL: easy_menus-1.3.6-py3-none-any.whl
  • Upload date:
  • Size: 14.5 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/7.0.0 CPython/3.10.8

File hashes

Hashes for easy_menus-1.3.6-py3-none-any.whl
Algorithm Hash digest
SHA256 b40c36dcf817674aa8672c479bfd3745dadfb1ebc920dbe58d6561740f22838e
MD5 47cbd65b96b36a8b3ac4d37fa3aeba1f
BLAKE2b-256 3ca5d3133f1b68eae45108b9dcaf1407e9edfeeec0bddd284d8b2ec01f4e32f1

See more details on using hashes here.

Release history Release notifications | RSS feed

This release

1.3.6 This release

2 files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page