You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

用Vala开发带菜单栏的Gtk4应用:编译正常但菜单栏不显示求助

问题:Gtk4应用菜单栏无法显示

我尝试用Vala编写一个简单的Gtk4应用,想添加一个包含两项功能的菜单栏:打印“Hello, World”和退出程序。使用命令:

valac --pkg=gtk4 menutest.vala

编译正常完成,窗口能显示,但菜单栏在macOS(通过Homebrew部署环境)和Fedora系统中都不出现。

以下是我的代码:

// 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 ();
    }
}

运行效果:

  • macOS系统:窗口正常显示,但屏幕顶部和窗口内均无菜单栏
  • Fedora系统:窗口正常显示,但窗口内无菜单栏

请问哪里操作出错了?


解决方案

问题核心是Gtk4中Gtk.Menu已被废弃,它属于旧版菜单API,不再适用于创建应用菜单栏。你需要改用Gtk4推荐的Gio.MenuModel结合Gtk.MenuBar的方式实现。

修改后的代码如下:

// 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";

        // 创建Gtk4推荐的菜单模型
        var menu_model = new Gio.Menu();
        menu_model.append("Hello", "app.hello");
        menu_model.append("Quit", "app.quit");

        // 创建菜单栏并绑定模型
        var menubar = new Gtk.MenuBar();
        menubar.menu_model = menu_model;

        // 创建垂直容器承载菜单栏(Gtk4窗口需要明确设置子组件)
        var main_box = new Gtk.Box(Gtk.Orientation.VERTICAL, 0);
        main_box.append(menubar);
        window.child = main_box;

        // 注册菜单动作
        var hello_action = new SimpleAction("hello", null);
        hello_action.activate.connect(() => {
            print("Hello, world!\n");
        });
        add_action(hello_action);

        var quit_action = new SimpleAction("quit", null);
        quit_action.activate.connect(() => {
            quit();
        });
        add_action(quit_action);

        window.present();
    }

    public static int main (string[] args) {
        return new Menutest().run(args);
    }
}

补充说明:

  • 在macOS上,Gtk4默认会将应用菜单合并到系统顶部菜单栏,若想强制菜单栏显示在窗口内,可添加以下代码(在window.present()前):
    var settings = Gtk.Settings.get_default();
    settings.set_string("gtk-decoration-layout", "menubar:");
    
  • 编译命令保持不变,重新编译运行后,菜单栏即可正常显示。

内容的提问来源于stack exchange,提问作者AthanasiusOfAlex

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.07 03:11:23