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

如何用C语言结合GTK4编写简易右键上下文菜单?附GTK3代码

GTK4 实现右键上下文菜单(GTK3代码迁移方案)

GTK4中废弃了GtkMenu、GtkMenuShell、GtkMenuItem等旧菜单组件,改用GtkPopover作为弹出容器,配合按钮类组件实现上下文菜单。以下是对应你GTK3代码的GTK4实现:

完整示例代码

#include <gtk/gtk.h>

// 菜单选择回调函数,和原逻辑一致
void on_popup_menu_selection(GtkWidget *button, gpointer user_data) {
    const gchar *item_text = (const gchar *)user_data;
    g_print("Selected: %s\n", item_text);
}

// 右键点击事件处理,触发菜单弹出
gboolean on_widget_button_press(GtkWidget *widget, GdkEventButton *event, gpointer user_data) {
    GtkWidget *popover = GTK_WIDGET(user_data);
    // 响应右键点击(GDK_BUTTON_SECONDARY)
    if (event->button == GDK_BUTTON_SECONDARY) {
        // 将菜单定位到鼠标点击位置
        gtk_popover_set_pointing_to(GTK_POPOVER(popover), &event->area);
        gtk_popover_popup(GTK_POPOVER(popover));
        return TRUE; // 拦截事件,避免触发其他默认行为
    }
    return FALSE;
}

int main(int argc, char *argv[]) {
    gtk_init(&argc, &argv);

    // 创建主窗口(作为菜单的父控件)
    GtkWidget *window = gtk_window_new();
    gtk_window_set_title(GTK_WINDOW(window), "GTK4 右键菜单示例");
    gtk_window_set_default_size(GTK_WINDOW(window), 400, 300);

    // 1. 创建Popover作为菜单容器,关联到主窗口
    GtkWidget *popover = gtk_popover_new(window);
    // 设置菜单为瞬态,点击外部自动关闭
    gtk_popover_set_autohide(GTK_POPOVER(popover), TRUE);

    // 2. 创建垂直盒子,用于容纳菜单项
    GtkWidget *menu_box = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0);
    gtk_popover_set_child(GTK_POPOVER(popover), menu_box);

    // 3. 创建菜单项(用GtkModelButton更贴近原生菜单样式)
    GtkWidget *item1 = gtk_model_button_new_with_label("Item 1");
    GtkWidget *item2 = gtk_model_button_new_with_label("Item 2");
    GtkWidget *item3 = gtk_model_button_new_with_label("Item 3");

    // 4. 绑定菜单项点击信号
    g_signal_connect(item1, "clicked", G_CALLBACK(on_popup_menu_selection), "Item 1");
    g_signal_connect(item2, "clicked", G_CALLBACK(on_popup_menu_selection), "Item 2");
    g_signal_connect(item3, "clicked", G_CALLBACK(on_popup_menu_selection), "Item 3");

    // 5. 将菜单项添加到盒子中
    gtk_box_append(GTK_BOX(menu_box), item1);
    gtk_box_append(GTK_BOX(menu_box), item2);
    gtk_box_append(GTK_BOX(menu_box), item3);

    // 6. 给主窗口绑定右键点击事件
    g_signal_connect(window, "button-press-event", G_CALLBACK(on_widget_button_press), popover);

    // 窗口关闭信号
    g_signal_connect(window, "destroy", G_CALLBACK(gtk_main_quit), NULL);

    gtk_widget_show(window);
    gtk_main();

    return 0;
}

关键差异说明

  • 容器替换:原GtkMenu替换为GtkPopover,原GtkMenuShell的布局功能由GtkBox承担
  • 菜单项替换:原GtkMenuItem替换为GtkModelButton(或GtkButton),GtkModelButton提供更贴合菜单的原生样式(悬停高亮、点击反馈)
  • 显示逻辑:GTK4无需手动调用gtk_widget_show_all(),子组件添加到容器后会自动被管理显示
  • 弹出触发:通过gtk_popover_popup()弹出菜单,使用gtk_popover_set_pointing_to()将菜单定位到鼠标点击位置
  • 自动关闭:通过gtk_popover_set_autohide()设置点击菜单外部自动关闭,符合现代UI行为

编译命令

使用以下命令编译(需安装GTK4开发库):

gcc -o gtk4_popup_menu gtk4_popup_menu.c `pkg-config --cflags --libs gtk4`

内容的提问来源于stack exchange,提问作者René Rigault

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.26 16:17:19