I attempted to make a simple Gtk4 application, and I tried to add a menu bar with a menu that does two things: print “Hello, World” and quit.
The code compiles as expected with the command
valac --pkg=gtk4 menutest.vala
However, although the window appears, the menu bar does not. I have tried this in both macOS (using Homebrew) and Fedora. What am I doing wrong?
Here is the sample code:
// menutest.vala
using Gtk;
public class Menutest : Gtk.Application {
public Menutest() {
Object (application_id: "org.gtk.menutest");
}
protected override void activate() {
var window = new ApplicationWindow (this);
window.title = "Hello World";
// Create a menu with two items
var menu = new Menu();
menu.insert(0, "Hello", "app.hello");
menu.insert(1, "Quit", "app.quit");
// Set the menu as the application's menubar
this.set_menubar(menu);
// Define the actions for the menu items
SimpleAction hello = new SimpleAction("hello", null);
hello.activate.connect(hello_action);
this.add_action(hello);
SimpleAction quit = new SimpleAction("quit", null);
quit.activate.connect(quit_action);
this.add_action(quit);
window.present();
}
public static int main (string[] args) {
return new Menutest().run (args);
}
// The callback function for the "Hello" action
private void hello_action (SimpleAction action, Variant? parameter) {
print ("Hello, world!\n");
}
// The callback function for the "Quit" action
private void quit_action (SimpleAction action, Variant? parameter) {
this.quit ();
}
}
The result in macOS (no menus are added at the top of the screen either):
The result in Fedora:
The issue was that you were missing a submenu item for the menu bar. After adding the submenu, the code now works as expected:
using Gtk;
public class Menutest : Gtk.Application {
public Menutest() {
Object (application_id: "org.gtk.menutest");
}
protected override void activate() {
var window = new ApplicationWindow (this);
window.title = "Hello World";
// Create root menu (menu bar).
var menu = new Menu ();
// Create window submenu and insert (The "Window" entry you'll see in the menu bar)
var window_menu = new Menu ();
window_menu.insert(0, "Hello", "app.hello");
window_menu.insert(1, "Quit", "app.quit");
// Add window submenu to menu bar
menu.append_submenu ("Window", window_menu);
// Set the menu as the application's menubar
this.set_menubar(menu);
window.set_show_menubar (true);
// Define the actions for the menu items
SimpleAction hello = new SimpleAction("hello", null);
hello.activate.connect(hello_action);
this.add_action(hello);
SimpleAction quit = new SimpleAction("quit", null);
quit.activate.connect(quit_action);
this.add_action(quit);
window.present();
}
public static int main (string[] args) {
return new Menutest().run (args);
}
// The callback function for the "Hello" action
private void hello_action (SimpleAction action, Variant? parameter) {
print ("Hello, world!\n");
}
// The callback function for the "Quit" action
private void quit_action (SimpleAction action, Variant? parameter) {
this.quit ();
}
}