Menus
Nota
Gtk.UIManager
, Gtk.Action
e Gtk.ActionGroup
foram descontinuados desde o GTK+ versão 3.10 e não devem ser usados em código recém-escrito. Use o framework Application.
O GTK+ vem com dois tipos diferentes de menus Gtk.MenuBar
e Gtk.Toolbar
. Gtk.MenuBar
é uma barra de menus padrão que contém uma ou mais instâncias Gtk.MenuItem
ou uma de suas subclasses. Os widgets Gtk.Toolbar
são usados para acessibilidade rápida às funções comumente usadas de um aplicativo. Exemplos incluem criar um novo documento, imprimir uma página ou desfazer uma operação. Ele contém uma ou mais instâncias de Gtk.ToolItem
ou uma de suas subclasses.
Ações
Embora existam APIs específicas para criar menus e barras de ferramentas, você deve usar Gtk.UIManager
e criar instâncias Gtk.Action
. As ações são organizadas em grupos. A Gtk.ActionGroup
é essencialmente um mapa de nomes para objetos Gtk.Action
. Todas as ações que fazem sentido usar em um contexto particular devem estar em um único grupo. Vários grupos de ação podem ser usados para uma interface de usuário específica. Na verdade, espera-se que a maioria dos aplicativos não triviais faça uso de vários grupos. Por exemplo, em um aplicativo que pode editar vários documentos, um grupo mantém ações globais (por exemplo, sair, sobre, novo) e um grupo por documento que contém ações que atuam nesse documento (por exemplo, salvar, recortar/copiar/colar etc. ). Os menus de cada janela seriam construídos a partir de uma combinação de dois grupos de ação.
Existem classes diferentes representando diferentes tipos de ações:
Gtk.Action
: Uma ação que pode ser acionada por um item de menu ou barra de ferramentasGtk.ToggleAction
: Uma ação que pode ser alternada entre dois estadosGtk.RadioAction
: Uma ação da qual apenas um em um grupo pode estar ativoGtk.RecentAction
: Uma ação que representa uma lista de arquivos usados recentemente
Ações representam operações que o usuário pode executar, juntamente com algumas informações sobre como ele deve ser apresentado na interface, incluindo seu nome (não para exibição), seu rótulo (para exibição), um acelerador, se um rótulo também indica uma dica de ferramenta como o retorno que é chamado quando a ação é ativada.
Você pode criar ações chamando um dos construtores diretamente e adicionando-os a um Gtk.ActionGroup
chamando Gtk.ActionGroup.add_action()
ou Gtk.ActionGroup.add_action_with_accel()
, ou chamando uma das funções de conveniência:
Observe que você deve especificar ações para submenus e itens de menu.
Gerenciador de interface de usuário
Gtk.UIManager
provides an easy way of creating menus and toolbars using
an XML-like description.
Primeiro de tudo, você deve adicionar o Gtk.ActionGroup
ao UI Manager com Gtk.UIManager.insert_action_group()
. Neste ponto também é uma boa ideia dizer à janela pai para responder aos atalhos de teclado especificados, usando Gtk.UIManager.get_accel_group()
e Gtk.Window.add_accel_group()
.
Em seguida, você pode definir o layout visível real dos menus e barras de ferramentas e adicionar o layout da interface do usuário. Essa “string de ui” usa um formato XML, no qual você deve mencionar os nomes das ações que você já criou. Lembre-se de que esses nomes são apenas os identificadores que usamos ao criar as ações. Eles não são o texto que o usuário verá nos menus e nas barras de ferramentas. Fornecemos esses nomes legíveis quando criamos as ações.
Finalmente, você obtém o widget raiz com Gtk.UIManager.get_widget()
e adiciona o widget a um contêiner como Gtk.Box
.
Exemplo
1import gi
2
3gi.require_version("Gtk", "3.0")
4from gi.repository import Gtk, Gdk
5
6UI_INFO = """
7<ui>
8 <menubar name='MenuBar'>
9 <menu action='FileMenu'>
10 <menu action='FileNew'>
11 <menuitem action='FileNewStandard' />
12 <menuitem action='FileNewFoo' />
13 <menuitem action='FileNewGoo' />
14 </menu>
15 <separator />
16 <menuitem action='FileQuit' />
17 </menu>
18 <menu action='EditMenu'>
19 <menuitem action='EditCopy' />
20 <menuitem action='EditPaste' />
21 <menuitem action='EditSomething' />
22 </menu>
23 <menu action='ChoicesMenu'>
24 <menuitem action='ChoiceOne'/>
25 <menuitem action='ChoiceTwo'/>
26 <separator />
27 <menuitem action='ChoiceThree'/>
28 </menu>
29 </menubar>
30 <toolbar name='ToolBar'>
31 <toolitem action='FileNewStandard' />
32 <toolitem action='FileQuit' />
33 </toolbar>
34 <popup name='PopupMenu'>
35 <menuitem action='EditCopy' />
36 <menuitem action='EditPaste' />
37 <menuitem action='EditSomething' />
38 </popup>
39</ui>
40"""
41
42
43class MenuExampleWindow(Gtk.Window):
44 def __init__(self):
45 super().__init__(title="Menu Example")
46
47 self.set_default_size(200, 200)
48
49 action_group = Gtk.ActionGroup(name="my_actions")
50
51 self.add_file_menu_actions(action_group)
52 self.add_edit_menu_actions(action_group)
53 self.add_choices_menu_actions(action_group)
54
55 uimanager = self.create_ui_manager()
56 uimanager.insert_action_group(action_group)
57
58 menubar = uimanager.get_widget("/MenuBar")
59
60 box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL)
61 box.pack_start(menubar, False, False, 0)
62
63 toolbar = uimanager.get_widget("/ToolBar")
64 box.pack_start(toolbar, False, False, 0)
65
66 eventbox = Gtk.EventBox()
67 eventbox.connect("button-press-event", self.on_button_press_event)
68 box.pack_start(eventbox, True, True, 0)
69
70 label = Gtk.Label(label="Right-click to see the popup menu.")
71 eventbox.add(label)
72
73 self.popup = uimanager.get_widget("/PopupMenu")
74
75 self.add(box)
76
77 def add_file_menu_actions(self, action_group):
78 action_filemenu = Gtk.Action(name="FileMenu", label="File")
79 action_group.add_action(action_filemenu)
80
81 action_filenewmenu = Gtk.Action(name="FileNew", stock_id=Gtk.STOCK_NEW)
82 action_group.add_action(action_filenewmenu)
83
84 action_new = Gtk.Action(
85 name="FileNewStandard",
86 label="_New",
87 tooltip="Create a new file",
88 stock_id=Gtk.STOCK_NEW,
89 )
90 action_new.connect("activate", self.on_menu_file_new_generic)
91 action_group.add_action_with_accel(action_new, None)
92
93 action_group.add_actions(
94 [
95 (
96 "FileNewFoo",
97 None,
98 "New Foo",
99 None,
100 "Create new foo",
101 self.on_menu_file_new_generic,
102 ),
103 (
104 "FileNewGoo",
105 None,
106 "_New Goo",
107 None,
108 "Create new goo",
109 self.on_menu_file_new_generic,
110 ),
111 ]
112 )
113
114 action_filequit = Gtk.Action(name="FileQuit", stock_id=Gtk.STOCK_QUIT)
115 action_filequit.connect("activate", self.on_menu_file_quit)
116 action_group.add_action(action_filequit)
117
118 def add_edit_menu_actions(self, action_group):
119 action_group.add_actions(
120 [
121 ("EditMenu", None, "Edit"),
122 ("EditCopy", Gtk.STOCK_COPY, None, None, None, self.on_menu_others),
123 ("EditPaste", Gtk.STOCK_PASTE, None, None, None, self.on_menu_others),
124 (
125 "EditSomething",
126 None,
127 "Something",
128 "<control><alt>S",
129 None,
130 self.on_menu_others,
131 ),
132 ]
133 )
134
135 def add_choices_menu_actions(self, action_group):
136 action_group.add_action(Gtk.Action(name="ChoicesMenu", label="Choices"))
137
138 action_group.add_radio_actions(
139 [
140 ("ChoiceOne", None, "One", None, None, 1),
141 ("ChoiceTwo", None, "Two", None, None, 2),
142 ],
143 1,
144 self.on_menu_choices_changed,
145 )
146
147 three = Gtk.ToggleAction(name="ChoiceThree", label="Three")
148 three.connect("toggled", self.on_menu_choices_toggled)
149 action_group.add_action(three)
150
151 def create_ui_manager(self):
152 uimanager = Gtk.UIManager()
153
154 # Throws exception if something went wrong
155 uimanager.add_ui_from_string(UI_INFO)
156
157 # Add the accelerator group to the toplevel window
158 accelgroup = uimanager.get_accel_group()
159 self.add_accel_group(accelgroup)
160 return uimanager
161
162 def on_menu_file_new_generic(self, widget):
163 print("A File|New menu item was selected.")
164
165 def on_menu_file_quit(self, widget):
166 Gtk.main_quit()
167
168 def on_menu_others(self, widget):
169 print("Menu item " + widget.get_name() + " was selected")
170
171 def on_menu_choices_changed(self, widget, current):
172 print(current.get_name() + " was selected.")
173
174 def on_menu_choices_toggled(self, widget):
175 if widget.get_active():
176 print(widget.get_name() + " activated")
177 else:
178 print(widget.get_name() + " deactivated")
179
180 def on_button_press_event(self, widget, event):
181 # Check if right mouse button was preseed
182 if event.type == Gdk.EventType.BUTTON_PRESS and event.button == 3:
183 self.popup.popup(None, None, None, None, event.button, event.time)
184 return True # event has been handled
185
186
187window = MenuExampleWindow()
188window.connect("destroy", Gtk.main_quit)
189window.show_all()
190Gtk.main()