如何用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
相关产品推荐
相关产品推荐

