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

GTK4中GtkPopoverMenuBar编译报错问题求助

问题:GTK4中GtkPopoverMenuBar编译报错(标识符未定义)

我正在基于GTK4教程开发C语言应用,使用GtkPopoverMenuBar组件,但编译时GCC提示identifier "GtkPopoverMenuBar" is undefined,无法识别gtk/gtkpopovermenubar.h。

当前代码

#include <gtk/gtk.h>

static void
quit_activated(GSimpleAction *action, GVariant *parameter, GApplication *application) {
    g_application_quit (application);
}

static void
app_activate (GApplication *application) {
  GtkApplication *app = GTK_APPLICATION (application);
  GtkWidget *win = gtk_application_window_new (GTK_APPLICATION (app));
  gtk_window_set_title (GTK_WINDOW (win), "menu1");
  gtk_window_set_default_size (GTK_WINDOW (win), 400, 300);

  gtk_application_window_set_show_menubar (GTK_APPLICATION_WINDOW (win), TRUE);
  gtk_window_present (GTK_WINDOW (win));
}

static void
app_startup (GApplication *application) {
  GtkApplication *app = GTK_APPLICATION (application);
  //GtkWidget *win = GTK_WIDGET(gtk_application_get_active_window(app));
  //GtkWidget *boxv = gtk_window_get_child(GTK_WINDOW(win));

  GSimpleAction *act_quit = g_simple_action_new ("quit", NULL);
  g_action_map_add_action (G_ACTION_MAP (app), G_ACTION (act_quit));
  g_signal_connect (act_quit, "activate", G_CALLBACK (quit_activated), application);

  GMenu *menubar = g_menu_new ();
  GtkPopoverMenuBar *popover_menubar = gtk_popover_menu_bar_new_from_model (menubar);
  GMenuItem *menu_item_file = g_menu_item_new ("File", NULL);
  GMenu *menu = g_menu_new ();
  GMenuItem *menu_item_quit = g_menu_item_new ("Quit", "app.quit");
  g_menu_append_item (menu, menu_item_quit);
  g_object_unref (menu_item_quit);
  g_menu_item_set_submenu (menu_item_file, G_MENU_MODEL (menu));
  g_menu_append_item (menubar, menu_item_file);
  g_object_unref (menu_item_file);

  //gtk_box_pack_start(GTK_BOX(boxv), GTK_WIDGET(popover_menubar), TRUE, FALSE, 0);

  gtk_application_set_menubar (GTK_APPLICATION (app), G_MENU_MODEL (menubar));
}

#define APPLICATION_ID "com.github.ToshioCP.menu1"

int
main (int argc, char **argv) {
  GtkApplication *app;
  int stat;

  app = gtk_application_new (APPLICATION_ID, G_APPLICATION_DEFAULT_FLAGS);
  g_signal_connect (app, "startup", G_CALLBACK (app_startup), NULL);
  g_signal_connect (app, "activate", G_CALLBACK (app_activate), NULL);

  stat = g_application_run (G_APPLICATION (app), argc, argv);
  g_object_unref (app);
  return stat;
}

VSCode tasks.json配置

{
    "tasks": [
        {
            "type": "cppbuild",
            "label": "C/C++: gcc.exe build active file",
            "command": "C:\\msys64\\mingw64\\bin\\gcc.exe",
            "args": [
                "-fdiagnostics-color=always",
                "-g",
                "-IC:/msys64/mingw64/bin/../include/libadwaita-1",
                "-IC:/msys64/mingw64/bin/../include/gtk-4.0",
                "-IC:/msys64/mingw64/bin/../include/pango-1.0",
                "-IC:/msys64/mingw64/bin/../include",
                "-IC:/msys64/mingw64/bin/../include/glib-2.0",
                "-IC:/msys64/mingw64/bin/../lib/glib-2.0/include",
                "-IC:/msys64/mingw64/bin/../include/harfbuzz",
                "-IC:/msys64/mingw64/bin/../include/freetype2",
                "-IC:/msys64/mingw64/bin/../include/libpng16",
                "-IC:/msys64/mingw64/bin/../include/fribidi",
                "-IC:/msys64/mingw64/bin/../include/cairo",
                "-IC:/msys64/mingw64/bin/../include/pixman-1",
                "-IC:/msys64/mingw64/bin/../include/gdk-pixbuf-2.0",
                "-IC:/msys64/mingw64/bin/../include/webp",
                "-IC:/msys64/mingw64/bin/../include/graphene-1.0",
                "-IC:/msys64/mingw64/bin/../lib/graphene-1.0/include",
                "${file}",
                "-LC:/msys64/mingw64/bin/../lib",
                "-ladwaita-1",
                "-lgtk-4",
                "-lpangowin32-1.0",
                "-lpangocairo-1.0",
                "-lpango-1.0",
                "-lharfbuzz",
                "-lgdk_pixbuf-2.0",
                "-lcairo-gobject",
                "-lcairo",
                "-lgraphene-1.0",
                "-lgio-2.0",
                "-lgobject-2.0",
                "-lglib-2.0",
                "-lintl",
                "-o",
                "${fileDirname}\\..\\bin\\${fileBasenameNoExtension}.exe"
            ],
            "options": {
                "cwd": "${fileDirname}"
            },
            "problemMatcher": [
                "$gcc"
            ],
            "group": {
                "kind": "build",
                "isDefault": true
            },
            "detail": "Task generated by Debugger."
        }
    ],
    "version": "2.0.0"
}

解决方案

  • 检查GTK4版本:GtkPopoverMenuBar是GTK 4.10及以上版本新增的组件,先通过pkg-config --modversion gtk4命令查看当前安装的GTK4版本。如果版本低于4.10,需要通过MSYS2的包管理器升级GTK4(执行pacman -S mingw-w64-x86_64-gtk4)。

  • 修正代码逻辑:你当前代码同时混用了传统应用菜单栏和GtkPopoverMenuBar,二者不可同时使用。若要使用GtkPopoverMenuBar,需调整代码:

    1. 删除gtk_application_set_menubar的调用
    2. 在app_activate函数中创建垂直容器并添加到窗口,再将GtkPopoverMenuBar放入容器:
      static void
      app_activate (GApplication *application) {
        GtkApplication *app = GTK_APPLICATION (application);
        GtkWidget *win = gtk_application_window_new (GTK_APPLICATION (app));
        gtk_window_set_title (GTK_WINDOW (win), "menu1");
        gtk_window_set_default_size (GTK_WINDOW (win), 400, 300);
      
        // 创建垂直容器
        GtkWidget *boxv = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0);
        gtk_window_set_child(GTK_WINDOW(win), boxv);
      
        // 移动GtkPopoverMenuBar的创建逻辑到此处(或确保窗口已创建后再执行)
        GMenu *menubar = g_menu_new ();
        GtkWidget *popover_menubar = gtk_popover_menu_bar_new_from_model (G_MENU_MODEL(menubar));
        GMenuItem *menu_item_file = g_menu_item_new ("File", NULL);
        GMenu *menu = g_menu_new ();
        GMenuItem *menu_item_quit = g_menu_item_new ("Quit", "app.quit");
        g_menu_append_item (menu, menu_item_quit);
        g_object_unref (menu_item_quit);
        g_menu_item_set_submenu (menu_item_file, G_MENU_MODEL (menu));
        g_menu_append_item (menubar, menu_item_file);
        g_object_unref (menu_item_file);
      
        // 将菜单栏添加到容器(GTK4用gtk_box_append替代GTK3的gtk_box_pack_start)
        gtk_box_append(GTK_BOX(boxv), popover_menubar);
      
        gtk_window_present (GTK_WINDOW (win));
      }
      

    同时,将app_startup中与菜单相关的代码移到app_activate(因为startup阶段窗口尚未创建),只保留动作注册的逻辑。

  • 用pkg-config自动生成编译参数:手动指定include和link参数容易遗漏依赖,建议修改tasks.json的args部分,利用pkg-config自动获取正确参数:

    "args": [
        "-fdiagnostics-color=always",
        "-g",
        "${file}",
        "-o",
        "${fileDirname}\\..\\bin\\${fileBasenameNoExtension}.exe",
        "`pkg-config --cflags gtk4`",
        "`pkg-config --libs gtk4`"
    ]
    

    注意:需确保VSCode使用MSYS2的bash终端运行编译任务,否则无法解析命令替换。若用Windows cmd,可先执行pkg-config --cflags gtk4和pkg-config --libs gtk4,将输出结果手动粘贴到args中。

  • 手动包含头文件:若版本达标仍报错,可尝试在代码开头手动添加#include <gtk/gtkpopovermenubar.h>,确认系统中存在该头文件。如果找不到,说明GTK4安装不完整,需重新安装或升级。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.28 06:07:08