Menyer
Observera
Gtk.UIManager
, Gtk.Action
och Gtk.ActionGroup
är föråldrade sedan GTK+ version 3.4 och bör inte användas i nyskriven kod. Använd ramverket Application istället.
GTK+ kommer med två olika sorters menyer, Gtk.MenuBar
och Gtk.Toolbar
. Gtk.MenuBar
är en standardmenyrad vilken innehåller en eller flera instanser av Gtk.MenuItem
eller en av dess underklasser. Gtk.Toolbar
-komponenter används för snabb åtkomst till vanligen använda funktioner för ett program. Exempel inkluderar att skapa ett nytt dokument, skriva ut en sida eller ångra en operation. Den innehåller en eller flera instanser av Gtk.ToolItem
eller en av dess underklasser.
Åtgärder
Även om det finns specifika API:er för att skapa menyer och verktygsfält så bör du använda Gtk.UIManager
och skapa Gtk.Action
-instanser. Åtgärder organiseras i grupper. En Gtk.ActionGroup
är i huvudsak en avbildning från namn till Gtk.Action
-objekt. Alla åtgärder som skulle vara rimliga att använda i ett visst sammanhang bör vara i en enskild grupp. Flera åtgärdsgrupper kan användas för ett specifikt användargränssnitt. Det förväntas faktiskt att de flesta icke-triviala programmen använder flera grupper. Exempelvis ett program som kan redigera flera dokument, med en grupp som innehåller globala åtgärder (t.ex. avsluta, om, nytt), och en grupp per dokument som innehåller åtgärder som agerar på det dokumentet (t.ex. spara, klipp ut/kopiera/klistra in o.s.v.). Varje fönsters menyer skulle då konstrueras från en kombination av två åtgärdsgrupper.
Det finns olika klasser som representerar olika typer av åtgärd:
Gtk.Action
: En åtgärd som kan utlösas genom ett meny- eller verktygsfältsobjektGtk.ToggleAction
: En åtgärd som kan växlas mellan två tillståndGtk.RadioAction
: En åtgärd för vilken endast en i en grupp kan vara aktivGtk.RecentAction
: En åtgärd som representerar en lista över senast använda filer
Åtgärder representerar operationer som användaren kan utföra, tillsammans med lite information om hur det ska visas i gränssnittet, inklusive dess namn (ej för visning), dess etikett (för visning), en snabbtangent, huruvida en etikett indikerar en inforuta såväl som återanropet som anropas när åtgärden aktiveras.
Du kan skapa åtgärder antingen genom att anropa en av konstruktorerna direkt och lägga till dem till en Gtk.ActionGroup
genom att anropa Gtk.ActionGroup.add_action()
eller Gtk.ActionGroup.add_action_with_accel()
, eller genom att anropa en av bekvämlighetsfunktionerna:
Observera att du måste ange åtgärder för undermenyer såväl som för menyobjekt.
Användargränssnittshanterare
Gtk.UIManager
provides an easy way of creating menus and toolbars using
an XML-like description.
Först bör du lägga till Gtk.ActionGroup
till användargränssnittshanteraren med Gtk.UIManager.insert_action_group()
. Vid denna punkt är det också god idé att säga till föräldrafönstret att svara på de angivna tangentbordsgenvägarna genom att använda Gtk.UIManager.get_accel_group()
och Gtk.Window.add_accel_group()
.
Sedan kan du definiera den faktiska synliga layouten för menyerna och verktygsfälten, och lägga till användargränssnittslayouten. Denna ”ui-sträng” använder ett XML-format, i vilket du bör nämna namnen på åtgärderna som du redan skapat. Kom ihåg att dessa namn bara är identifierarna som vi använde då vi skapade åtgärderna. De är inte texten som användaren kommer se i menyerna och verktygsfälten. Vi tillhandahöll dessa mänskligt läsbara namn då vi skapade åtgärderna.
Slutligen erhåller du rotkomponenten med Gtk.UIManager.get_widget()
och lägger till komponenten till en behållare så som Gtk.Box
.
Exempel
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()