[GTK4][C] 动作应该如何与菜单项连接?

问题描述

我正在用 C 语言编写一个使用 GTK4 的应用程序。我试图将一些操作与菜单项联系起来,但这些项是非活动的,即它们在出现时不可点击。我不知道解决此问题的方法,因此不胜感激。

部分代码如下。

#include <gtk/gtk.h>

int main(int argc,char **argv)
{
    int status;
    
    application = gtk_application_new("gtk.example",G_APPLICATION_FLAGS_NONE);
    g_signal_connect_swapped(application,"active" G_CALL_BACK(create_window),application);

    status = g_application_run(G_APPLICATION(application),argc,argv);
    g_object_unref(application);
    return status;
}

void create_window(GtkApplication *application)
{
    GMenu *menubar;
    GMenu *menu;
    GMenuItem *item;

    window = gtk_application_window_new(application);
    gtk_window_set_application(GTK_WINDOW(window),application);
    
    const GActionEntry entries[] =
    {
        {"close",quit}
    };
    g_action_map_add_action_entries(G_ACTION_MAP(application),entries,G_N_ELEMENTS(entries),NULL);

    menubar = g_menu_new();
    menu = g_menu_new();
    item = g_menu_item_new("Close","app.close");
    g_menu_append_item(menu,item);
    g_object_unref(item);
    
    g_menu_append_submenu(menubar,"File",G_MENU_MODEL(menu));
    g_object_unref(menu);

    gtk_application_set_menubar(application,G_MENU_MODEL(menubar));
    gtk_application_window_set_show_menubar(GTK_APPLICATION_WINDOW(window),TRUE);
    gtk_window_present(GTK_WINDOW(window));        
}

static void quit(GSimpleAction *action,GVariant *parameter,gpointer data)
{
    g_print("You choose close action\n");
}

我得到的结果如下。关闭不可点击。

enter image description here

解决方法

你的代码有很多问题,我不知道应该从哪里开始。

无论如何,主要问题(但不是唯一的)就在这里:

const GActionEntry entries[] =
{
    {"close",quit}
};

应该是这样的:

const GActionEntry entries[] =
{
    {"close",quit,NULL,{ 0,0 } }
};

这是一个工作程序

#include <gtk/gtk.h>

void create_window ( GtkApplication *application );
static void quit   ( GSimpleAction *action,GVariant *parameter,gpointer data );

int main ( int argc,char **argv )
{
    GtkApplication *application;
    int status;

    /// ***
    application = gtk_application_new ( "gtk.example",G_APPLICATION_FLAGS_NONE );
    g_signal_connect_swapped ( application,"activate",G_CALLBACK ( create_window ),application );

    /// ***
    status = g_application_run ( G_APPLICATION ( application ),argc,argv );
    g_object_unref ( application );
    
    return status;
}

void create_window ( GtkApplication *application )
{
    GtkWidget *window;
    GMenu *menubar;
    GMenu *menu;
    GMenuItem *item;

    /// ***
    window = gtk_application_window_new ( application );
    gtk_window_set_application ( GTK_WINDOW ( window ),application );

    /// ***
    const GActionEntry entries[] =
    {
        {"close",0 } }
    };
    
    /// **
    g_action_map_add_action_entries ( G_ACTION_MAP ( application ),entries,G_N_ELEMENTS ( entries ),NULL );

    /// ***
    menubar = g_menu_new();
    menu    = g_menu_new();
    item    = g_menu_item_new ( "Close","app.close" );
    
    /// ***
    g_menu_append_item ( menu,item );
    g_object_unref ( item );

    /// ***
    g_menu_append_submenu ( menubar,"File",G_MENU_MODEL ( menu ) );
    g_object_unref ( menu );

    /// ***
    gtk_application_set_menubar ( application,G_MENU_MODEL ( menubar ) );
    gtk_application_window_set_show_menubar ( GTK_APPLICATION_WINDOW ( window ),TRUE );
    
    /// ***
    gtk_window_present ( GTK_WINDOW ( window ) );
}

static void quit ( GSimpleAction *action,G_GNUC_UNUSED GVariant *parameter,G_GNUC_UNUSED gpointer data )
{
    g_print ( "You choose `%s` action\n",g_action_get_name ( G_ACTION( action ) ) );
}

我强烈建议您to check these Videos

顺便说一下,没有 active 信号,您需要 activate 代替。