How to create menus in GTK 4 with pygi?

I've googled about this quite a bit. I've put a number of examples of what I tried Read more - I'm going to quote the closest one immediately below in case of link rot:
import gi
gi.require_version("Gtk", "4.0")
from gi.repository import Gtk, Gio
class ExampleApp(Gtk.Application):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.window = None
def do_activate(self):
if not self.window:
self.window = Gtk.ApplicationWindow(application=self, title="GMenu Example")
menu_bar = self.create_menu()
self.window.set_menu_bar(menu_bar)
self.window.present()
def create_menu(self):
menu_bar = Gio.Menu()
file_menu = Gio.Menu()
file_menu.append("New", "app.new")
file_menu.append("Quit", "app.quit")
edit_menu = Gio.Menu()
edit_menu.append("Copy", "app.copy")
edit_menu.append("Paste", "app.paste")
menu_bar.append_submenu("File", file_menu)
menu_bar.append_submenu("Edit", edit_menu)
# Create actions
new_action = Gio.SimpleAction.new("new", None)
new_action.connect("activate", self.on_new_action)
self.add_action(new_action)
quit_action = Gio.SimpleAction.new("quit", None)
quit_action.connect("activate", self.on_quit_action)
self.add_action(quit_action)
copy_action = Gio Brainly.SimpleAction.new("copy", None)
copy_action.connect("activate", self.on_copy_action)
self.add_action(copy_action)
paste_action = Gio.SimpleAction.new("paste", None)
paste_action.connect("activate", self.on_paste_action)
self.add_action(paste_action)
return menu_bar
def on_new_action(self, action, param):
print("New action triggered")
def on_quit_action(self, action, param):
self.quit()
def on_copy_action(self, action, param):
print("Copy action triggered")
def on_paste_action(self, action, param):
print("Paste action triggered")
if __name__ == "__main__":
app = ExampleApp(application_id="com.example.GMenuExample")
app.run(None)
Answer
This actually works:
#!/usr/bin/env python3
"""
A tiny Gtk 4.0 Menu example program.
This working example is in part due to chrisawi on Reddit.
"""
import gi
gi.require_version("Gtk", "4.0")
from gi.repository import Gtk, Gio
class ExampleApp(Gtk.Application):
"""The 'application'."""
def __init__(self, *args, **kwargs):
"""Init."""
super().__init__(*args, **kwargs)
self.window = None
def do_activate(self):
"""Activate the Window (if it doesn't yet exist)."""
if not self.window:
self.window = Gtk.ApplicationWindow(application=self, title="GMenu Example")
menu_bar = self.create_menu()
self.set_menubar(menu_bar)
self.window.set_show_menubar(True)
self.window.present()
def create_menu(self):
"""Create the menu - our reason for this example program."""
menu_bar = Gio.Menu()
file_menu = Gio.Menu()
file_menu.append("New", "app.new")
file_menu.append("Quit", "app.quit")
edit_menu = Gio.Menu()
edit_menu.append("Copy", "app.copy")
edit_menu.append("Paste", "app.paste")
menu_bar.append_submenu("File", file_menu)
menu_bar.append_submenu("Edit", edit_menu)
# Create actions
new_action = Gio.SimpleAction.new("new", None)
new_action.connect("activate", self.on_new_action)
self.add_action(new_action)
quit_action = Gio.SimpleAction.new("quit", None)
quit_action.connect("activate", self.on_quit_action)
self.add_action(quit_action)
copy_action = Gio.SimpleAction.new("copy", None)
copy_action.connect("activate", self.on_copy_action)
self.add_action(copy_action)
paste_action = Gio.SimpleAction.new("paste", None)
paste_action.connect("activate", self.on_paste_action)
self.add_action(paste_action)
return menu_bar
def on_new_action(self, action, param):
"""File -> New was selected."""
print("New action triggered")
def on_quit_action(self, action, param):
"""File -> Quit was selected."""
self.quit()
def on_copy_action(self, action, param):
"""Edit -> Copy was selected."""
print("Copy action triggered")
def on_paste_action(self, action, param):
"""Edit -> Paste was selected."""
print("Paste action triggered")
if __name__ == "__main__":
# Create the application as a global.
my_app = ExampleApp(application_id="com.example.GMenuExample")
my_app.run(None)
Enjoyed this article?
Check out more content on our blog or follow us on social media.
Browse more articles