Tkinter Menu
Summary: in this tutorial, you’ll learn how to create a Tkinter menu bar, add menus to the menu bar, and add menu items to each menu.
When an application contains a lot of functions, you need to use menus to organize them for easier navigation.
Typically, you use a menu to group closely related operations. For example, you can find the File menu in most text editors.
Tkinter natively supports menus. It displays menus with the look-and-feel of the target platform that the program runs e.g., Windows, macOS, and Linux.
Creating a simple menu
First, create a root window and set its title to ‘Menu Demo’ :
Second, create a menu bar and assign it to the menu option of the root window:
Note that each top-level window can only have only one menu bar.
Third, create a File menu whose container is the menubar :
Fourth, add a menu item to the file_menu :
In this example, the label of the menu item is Exit .
When you click the Exit menu item, Python will call the root.destroy() method automatically to close the root window.
Finally, add the File menu to the menubar:
The underline option allows you to create a keyboard shortcut. It specifies the character position that should be underlined.
Note that the position starts from zero. In this example, we specify it as the first character which is F . And you can select it by using the Alt+F keyboard shortcut.
Put it all together:

By default, Tkinter adds a dashed line before the first menu item. When you click the dashed line, the main window will detach the menu from it like this:

To remove the dashed line, you can set the tearoff property of the menu to False :

Creating a more complex menu
The following program illustrates how to create a menu bar, add the File and Help menus to the menu bar. Also, it adds multiple menu items to these menus:

The only new statement in this program is to use the add_separator() method to add a separator to the menu.
Adding a submenu
The following program adds the menu item Preferences to the File menu and create a submenu that links the new menu item:

The following code adds a submenu to File menu and links the submenu to Preferences menu item:
Как сделать меню в python
Для создания иерархического меню в tkinter применяется виджет Menu . Основные параметры Menu:
activebackground : цвет активного пункта меню
activeborderwidth : толщина границы активного пункта меню
activeforeground : цвет текста активного пункта меню
background / bg : фоновый цвет
bd : толщина границы
cursor : курсор указателя мыши при наведении на меню
disabledforeground : цвет, когда меню находится в состоянии DISABLED
font : шрифт текста
foreground / fg : цвет текста
tearoff : меню может быть отсоединено от графического окна. В частности, при создании подменю а скриншоте можно увидеть прерывающуюся линию в верху подменю, за которую его можно отсоединить. Однако при значении tearoff=0 подменю не сможет быть отсоединено.
Меню может содержать много элементов, причем эти элементы сами могут представлять меню и содержать другие элементы. В зависимости от того, какой тип элементов мы хотим добавить в меню, будет отличаться метод, используемый для их добавления. В частности, нам доступны следующие методы:
add_command(options) : добавляет элемент меню через параметр options
add_cascade(options) : добавляет элемент меню, который в свою очередь может представлять подменю
add_separator() : добавляет линию-разграничитель
add_radiobutton(options) : добавляет в меню переключатель
add_checkbutton(options) : добавляет в меню флажок
Создадим простейшее меню:
Для добавления пунктов меню у объекта Menu вызывается метод add_cascade() . В этот метод передаются параметры пункта меню, в данном случае они представлены текстовой меткой, устанавливаемой через параметр label .
Но просто создать меню — еще недостаточно. Его надо установить для текущего окна с помощью параметра menu в методе config() . В итоге графическое окно будет иметь следующее меню:

Теперь добавим подменю:
Здесь определяется подменю file_menu, которое добавляется в первый пункт основного меню благодаря установке опции menu=file_menu :

Но обратите внимание на пунктирную линию в подменю, которая совершенно не нужна и непонятно откуда появляется. Чтобы избавиться от этой линии, надо для нужного пункта меню установить параметр tearoff=0 :
Однако так как подпунктов меню может быть много, чтобы для кажлого не прописывать этот параметр, то проще отключить все это глобально с помощью следующей строки кода

Подобным образом можно создавать и более глубокие иерархии меню:

Взаимодействие с меню
Отличительной особенностью элементов меню является способность реагировать на нажатия пользователя. Для этого у каждого элемента меню можно задать параметр command , который устанавливает ссылку на функцию, выполняемую при нажатии.
The Tkinter Menu Widget
The Menu widget is used to implement toplevel, pulldown, and popup menus.
When to use the Menu Widget
This widget is used to display all kinds of menus used by an application. Since this widget uses native code where possible, you shouldn’t try to fake menus using buttons and other Tkinter widgets.
Patterns #
Toplevel menus are displayed just under the title bar of the root or any other toplevel windows (or on Macintosh, along the upper edge of the screen). To create a toplevel menu, create a new Menu instance, and use add methods to add commands and other menu entries to it.
Pulldown menus (and other submenus) are created in a similar fashion. The main difference is that they are attached to a parent menu (using add_cascade), instead of a toplevel window.
Finally, a popup menu is created in the same way, but is explicitly displayed, using the post method:
You can use the postcommand callback to update (or even create) the menu every time it is displayed.
Reference #
Creates a menu widget.
master Parent widget. **options Widget options. See the description of the config method for a list of available options.
activate(index) [#]
The activate method.
Add (append) an entry of the given type to the menu.
type What kind of entry to add. Can be one of “command”, “cascade” (submenu), “checkbutton”, “radiobutton”, or “separator”. **options Menu options. activebackground= activeforeground= accelerator= background= bitmap= columnbreak= command= font= foreground= hidemargin= image= indicatoron= label= menu= offvalue= onvalue= selectcolor= selectimage= state= underline= value= variable=
add_cascade(**options) [#]
Adds a submenu. See add for a list of options.
Adds a checkbutton. See add for a list of options.
Adds a command. See add for a list of options.
Adds a radiobutton. See add for a list of options.
Adds a separator. See add for a list of options.
Modifies one or more widget options. If no options are given, the method returns a dictionary containing all current option values.
**options Widget options. activebackground= Default value is ‘SystemHighlight’. (the database name is activeBackground, the class is Foreground) activeborderwidth= Default value is 0. (activeBorderWidth/BorderWidth) activeforeground= Default value is ‘SystemHighlightText’. (activeForeground/Background) background= Default value is ‘SystemMenu’. (background/Background) bg= Same as background. borderwidth= Default value is 0. (borderWidth/BorderWidth) bd= Same as borderwidth. cursor= Default value is ‘arrow’. (cursor/Cursor) disabledforeground= Default value is ‘SystemDisabledText’. (disabledForeground/DisabledForeground) font= Default value is ‘MS Sans Serif 8’. (font/Font) foreground= Default value is ‘SystemMenuText’. (foreground/Foreground) fg= Same as foreground. postcommand= No default value. (postCommand/Command) relief= Default value is ‘flat’. (relief/Relief) selectcolor= Default value is ‘SystemMenuText’. (selectColor/Background) takefocus= Default value is 0. (takeFocus/TakeFocus) tearoff= Default value is 1. (tearOff/TearOff) tearoffcommand= No default value. (tearOffCommand/TearOffCommand) title= No default value. (title/Title) type= Default value is ‘normal’. (type/Type)
delete(index1, index2=None) [#]
Deletes one or more menu entries.
index1 The first entry to delete. index2 The last entry to delete. If omitted, only one entry is deleted.
entrycget(index, option) [#]
The entrycget method.
Reconfigures the given menu entry. Only the given options are changed; the rest are left as is. See add for a list of available options.
Converts an index (of any kind) to an integer index.
Inserts an entry of the given type in the menu. This is similar to add, but inserts an entry
Inserts a submenu.
Inserts a checkbutton.
Inserts a command.
Inserts a radiobutton.
Inserts a separator. def insert_separator(index, **options)
The invoke method.
Displays the menu at the given position. The position should be given in pixels, relative to the root window.
x Menu position. y Menu position.
type(index) [#]
Gets the type of the given menu entry.
index Index specifier. Returns: Item type.
unpost() [#]
Removes a posted menu.
Returns the vertical offset for the given entry. This can be used to position a popup menu so that a given entry is under the mouse when the menu appears.
index Index specifier. Returns: The vertical offset, in screen coordinates.
How to add Menus to Tkinter applications

In this post we’re going to learn how to make use of Tkinter’s Menu widget to create different types of menus in our GUI applications.
We’re going to be making use of a very simple application for this post. It doesn’t display anything, and until we add the menu, it won’t really do anything either. Tkinter’s Menu widgets are completely independent units, and don’t rely on anything in our application besides the root window.
To keep things simple, our starting code is therefore going be this:
We don’t even need to import ttk , as Menu widgets are not themed widgets. Our very exciting Tkinter application should look something like this:

Tkinter will try to match the window to your operating system, so don’t worry if yours looks a little different.
Creating our first menu
Adding a Menu widget to our application is much like adding any other element. We’re going be assigning the new Menu widget to the menubar variable, and we’ll be passing in root as the Menu parent.
We also need to add another line to tell the root window that this menubar is a menu for the window:
If you run the application at this point, you’re not likely to see a lot of difference. This is because our menu doesn’t have any content, so its height has collapsed to nearly zero.
So, how do we add items to the menu? We have a few options, but we’re going to start by adding simple buttons that trigger commands.
We can add a button by calling the add_command method on the Menu widget instance we created.
We’re going to pass in two pieces of configuration when calling this method: a label , and a command . We can set all kinds of other values, but most of them just control the appearance of the buttons in some way. We can also set the state to disable buttons, for example.
The value passed to the command parameter determines what happens when a user clicks the button, and the label determines how the option is going to display in the menu. You can also use image instead if you want.
Here are a couple of simple example buttons:
Note that we have to use lambda functions here, as we’re passing in arguments to print . If we write something like command=print(«Hello») , the function will run during the add_command execution, and the return value of print(«Hello») will be passed in as the value for the command parameter. Generally not what we want.
With that, our application now has a working menu!

If we click the Say Hello button, we get Hello printed to the console, and Say Goodbye prints Goodbye . Nothing crazy, but we can use the same principles to run any operations we want.
For example, we can replace Say Goodbye with a Quit button that closes the application using root.destroy .
No need for the lambda in this case, because we don’t want to pass in any arguments to the destroy method.
Dropdown Menus
When our programs get more complicated, we often want to be able to organise the application menu into various submenus for ease of navigation. The main menu then features a number of headings, each of which triggers a different dropdown menu.
To do this in Tkinter, we need to create a different Menu widget for each submenu, and one more for the menu bar itself.
Let’s start by creating a new menu called salutations which is going to house our Say Hello and Say Goodbye buttons.
Note that the parent of this Menu widget isn’t root : it’s the main menubar widget.
We can now add this new submenu to the menubar using the add_cascade method like so:
Once again we’ve set a label , which is going to determine the heading for this submenu. The menu parameter takes a Menu widget that will serve as the submenu associated with this label.
In total the code now looks something like this:
And our application can now do this:

Tear-off Menus
One thing you probably weren’t expecting was the dashed line above Say Hello . What does this mean? And why is it there?
This dashed line is meant to represent perforations, indicating that the menu can be torn off. This isn’t very common in modern applications, but it allows us to do something like this:

If you want to give your users the ability to detach menus and move them around the screen, you’re in luck, because this is the default behaviour! If you don’t want this, then we need to turn it off by passing in some additional configuration to our Menu widgets. Luckily it’s very simple, we just have to add an addition keyword argument.
The official documentation uses tearoff=0 , but tearoff=False also works, and I think it makes a lot more sense, so that’s what I’m using here:
Goodbye, tear-off menu:

Some Other Menu Options
In addition to buttons and submenus, we have a few other things we can add to our menus.
Here is a menu with some of these additional options:
First up, we have a checkbutton , which works very much like the main Checkbutton widget. We can specify a variable to hold the current checked state; we can set values for the checked and unchecked state; and we can set a command to trigger every time the checkbutton is clicked. In our case, it retrieves the new checked state from the variable.
Next we have the add_separator method, which adds a line to the menu to help distinguish groups of options. You can use it without any additional configuration.
Finally, we have some radiobutton items in the menu. Again, these work very much like the main Radiobutton widget. In the menu above, we’ve just set a variable to store which of the options are toggled, and we set a value for each button.
You can see an example of this menu below:

The add Method
In addition to these specialised methods like add_checkbutton , add_cascade , and add_command , there is also a generic add method.
We can use add to replicate any of the other methods: we just need to pass in the type of item to add as a string. This can be as a positional argument, or as a keyword argument using the key itemType :
Use whichever version you prefer.
Wrapping Up
That’s it for this post on Tkinter Menu widgets. I hope you learnt something new, and if you’re keen to dig deeper into Tkinter, be sure to check out our GUI development course!

Phil Best
I'm a freelance developer, mostly working in web development. I also create course content for Teclado!