Menus¶
Note
Gtk.UIManager
, Gtk.Action
, and Gtk.ActionGroup
have been deprecated since GTK+ version 3.10 and should not be used in
newly-written code. Use the Application framework instead.
GTK+ comes with two different types of menus, Gtk.MenuBar
and
Gtk.Toolbar
. Gtk.MenuBar
is a standard menu bar which contains
one or more Gtk.MenuItem
instances or one of its subclasses.
Gtk.Toolbar
widgets are used for quick accessibility to commonly used
functions of an application. Examples include creating a new document, printing
a page or undoing an operation. It contains one or more instances of
Gtk.ToolItem
or one of its subclasses.
Actions¶
Although, there are specific APIs to create menus and toolbars, you should
use Gtk.UIManager
and create Gtk.Action
instances.
Actions are organised into groups. A Gtk.ActionGroup
is essentially a
map from names to Gtk.Action
objects.
All actions that would make sense to use in a particular context should be in a
single group. Multiple action groups may be used for a particular user interface.
In fact, it is expected that most non-trivial applications will make use of
multiple groups. For example, in an application that can edit multiple documents,
one group holding global actions (e.g. quit, about, new), and one group per
document holding actions that act on that document (eg. save, cut/copy/paste, etc).
Each window’s menus would be constructed from a combination of two action groups.
Different classes representing different types of actions exist:
Gtk.Action
: An action which can be triggered by a menu or toolbar itemGtk.ToggleAction
: An action which can be toggled between two statesGtk.RadioAction
: An action of which only one in a group can be activeGtk.RecentAction
: An action of which represents a list of recently used files
Actions represent operations that the user can perform, along with some information how it should be presented in the interface, including its name (not for display), its label (for display), an accelerator, whether a label indicates a tooltip as well as the callback that is called when the action gets activated.
You can create actions by either calling one of the constructors directly and
adding them to a Gtk.ActionGroup
by calling
Gtk.ActionGroup.add_action()
or Gtk.ActionGroup.add_action_with_accel()
,
or by calling one of the convenience functions:
Note that you must specify actions for sub menus as well as menu items.
UI Manager¶
Gtk.UIManager
provides an easy way of creating menus and toolbars using
an XML-like description.
First of all, you should add the Gtk.ActionGroup
to the UI Manager with
Gtk.UIManager.insert_action_group()
. At this point is also a good idea to
tell the parent window to respond to the specified keyboard shortcuts, by using
Gtk.UIManager.get_accel_group()
and Gtk.Window.add_accel_group()
.
Then, you can define the actual visible layout of the menus and toolbars, and add the UI layout. This “ui string” uses an XML format, in which you should mention the names of the actions that you have already created. Remember that these names are just the identifiers that we used when creating the actions. They are not the text that the user will see in the menus and toolbars. We provided those human-readable names when we created the actions.
Finally, you retrieve the root widget with Gtk.UIManager.get_widget()
and add the widget to a container such as Gtk.Box
.
Example¶

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 | import gi
gi.require_version("Gtk", "3.0")
from gi.repository import Gtk, Gdk
UI_INFO = """
<ui>
<menubar name='MenuBar'>
<menu action='FileMenu'>
<menu action='FileNew'>
<menuitem action='FileNewStandard' />
<menuitem action='FileNewFoo' />
<menuitem action='FileNewGoo' />
</menu>
<separator />
<menuitem action='FileQuit' />
</menu>
<menu action='EditMenu'>
<menuitem action='EditCopy' />
<menuitem action='EditPaste' />
<menuitem action='EditSomething' />
</menu>
<menu action='ChoicesMenu'>
<menuitem action='ChoiceOne'/>
<menuitem action='ChoiceTwo'/>
<separator />
<menuitem action='ChoiceThree'/>
</menu>
</menubar>
<toolbar name='ToolBar'>
<toolitem action='FileNewStandard' />
<toolitem action='FileQuit' />
</toolbar>
<popup name='PopupMenu'>
<menuitem action='EditCopy' />
<menuitem action='EditPaste' />
<menuitem action='EditSomething' />
</popup>
</ui>
"""
class MenuExampleWindow(Gtk.Window):
def __init__(self):
super().__init__(title="Menu Example")
self.set_default_size(200, 200)
action_group = Gtk.ActionGroup(name="my_actions")
self.add_file_menu_actions(action_group)
self.add_edit_menu_actions(action_group)
self.add_choices_menu_actions(action_group)
uimanager = self.create_ui_manager()
uimanager.insert_action_group(action_group)
menubar = uimanager.get_widget("/MenuBar")
box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL)
box.pack_start(menubar, False, False, 0)
toolbar = uimanager.get_widget("/ToolBar")
box.pack_start(toolbar, False, False, 0)
eventbox = Gtk.EventBox()
eventbox.connect("button-press-event", self.on_button_press_event)
box.pack_start(eventbox, True, True, 0)
label = Gtk.Label(label="Right-click to see the popup menu.")
eventbox.add(label)
self.popup = uimanager.get_widget("/PopupMenu")
self.add(box)
def add_file_menu_actions(self, action_group):
action_filemenu = Gtk.Action(name="FileMenu", label="File")
action_group.add_action(action_filemenu)
action_filenewmenu = Gtk.Action(name="FileNew", stock_id=Gtk.STOCK_NEW)
action_group.add_action(action_filenewmenu)
action_new = Gtk.Action(
name="FileNewStandard",
label="_New",
tooltip="Create a new file",
stock_id=Gtk.STOCK_NEW,
)
action_new.connect("activate", self.on_menu_file_new_generic)
action_group.add_action_with_accel(action_new, None)
action_group.add_actions(
[
(
"FileNewFoo",
None,
"New Foo",
None,
"Create new foo",
self.on_menu_file_new_generic,
),
(
"FileNewGoo",
None,
"_New Goo",
None,
"Create new goo",
self.on_menu_file_new_generic,
),
]
)
action_filequit = Gtk.Action(name="FileQuit", stock_id=Gtk.STOCK_QUIT)
action_filequit.connect("activate", self.on_menu_file_quit)
action_group.add_action(action_filequit)
def add_edit_menu_actions(self, action_group):
action_group.add_actions(
[
("EditMenu", None, "Edit"),
("EditCopy", Gtk.STOCK_COPY, None, None, None, self.on_menu_others),
("EditPaste", Gtk.STOCK_PASTE, None, None, None, self.on_menu_others),
(
"EditSomething",
None,
"Something",
"<control><alt>S",
None,
self.on_menu_others,
),
]
)
def add_choices_menu_actions(self, action_group):
action_group.add_action(Gtk.Action(name="ChoicesMenu", label="Choices"))
action_group.add_radio_actions(
[
("ChoiceOne", None, "One", None, None, 1),
("ChoiceTwo", None, "Two", None, None, 2),
],
1,
self.on_menu_choices_changed,
)
three = Gtk.ToggleAction(name="ChoiceThree", label="Three")
three.connect("toggled", self.on_menu_choices_toggled)
action_group.add_action(three)
def create_ui_manager(self):
uimanager = Gtk.UIManager()
# Throws exception if something went wrong
uimanager.add_ui_from_string(UI_INFO)
# Add the accelerator group to the toplevel window
accelgroup = uimanager.get_accel_group()
self.add_accel_group(accelgroup)
return uimanager
def on_menu_file_new_generic(self, widget):
print("A File|New menu item was selected.")
def on_menu_file_quit(self, widget):
Gtk.main_quit()
def on_menu_others(self, widget):
print("Menu item " + widget.get_name() + " was selected")
def on_menu_choices_changed(self, widget, current):
print(current.get_name() + " was selected.")
def on_menu_choices_toggled(self, widget):
if widget.get_active():
print(widget.get_name() + " activated")
else:
print(widget.get_name() + " deactivated")
def on_button_press_event(self, widget, event):
# Check if right mouse button was preseed
if event.type == Gdk.EventType.BUTTON_PRESS and event.button == 3:
self.popup.popup(None, None, None, None, event.button, event.time)
return True # event has been handled
window = MenuExampleWindow()
window.connect("destroy", Gtk.main_quit)
window.show_all()
Gtk.main()
|