不使用 GtkBuilder 时,搜索在 GtkShortcutsWindow 中不起作用

Search does not work in GtkShortcutsWindow when not using GtkBuilder

我创建了一个 window,它使用 GtkShortcutsWindow 显示快捷方式。但是,我不想加载 extern .ui 文件并使用 gtk_builder_new_from_string requires quite 大字符串。通过创建必要的对象并将它们打包到 window 及其容器 GtkShortcutsSectionGtkShortcutsGroups 中,我想出了一个简洁的解决方案。结果看起来就像我会使用 gtk_builder_new_from_string(我已经尝试过两种方法),但是当不使用 GtkBuilder 时,built-in 搜索位于 window 不起作用,没有显示结果。我在这里错过了什么?以下是我的代码的相关部分:

enum { FILE_HNDL_GRP, EDITING_GRP, FIND_GRP, VIEW_GRP, HELP_GRP, NUMBER_OF_SC_GROUPS };

gchar *accels[] = { "", 
                    "<ctrl>N", "<ctrl>O", "<ctrl>S", "<ctrl><shift>S", "<ctrl>Q", 
                    "", 
                    "<ctrl>A", "<ctrl>backslash", "<ctrl>Z", "<ctrl>Y", "<ctrl>T", 
                    "<ctrl>minus", "<ctrl>plus", "<ctrl>B", "<ctrl>R", "<ctrl><shift>R", 
                    "", 
                    "<ctrl>F", "<ctrl>H", 
                    "", 
                    "<shift><ctrl>X", "<shift><ctrl>C", 
                    "", 
                    "<ctrl>L", "<shift><ctrl>A"
                  };

gchar *accel_txts[] = { "File Handling", 
                            "Create a new menu" , "Open a menu", "Save the menu", 
                            "Save the menu as...", "Quit the application", 
                        "Editing", 
                            "Select all visible nodes", "Deselect all visible nodes", "Undo previous edit", 
                            "Redo previous edit", "Move node to the top", "Move node up", "Move node down", 
                            "Move node to the bottom", "Remove node", "Remove children from node", 
                        "Find", 
                            "Show/Hide Find Grid", "Open/Close\nFind & Replace Window", 
                        "View", 
                            "Expand all nodes", "Collapse all nodes", 
                        "Help", 
                            "Open/Close\nShortcuts Window", "About"
                      };

guint8 number_of_shortcuts = sizeof (accels) / sizeof (accels[0]);

GtkShortcutsWindow *shortcuts_window;
GtkShortcutsSection *shortcuts_section;
GtkShortcutsGroup *shortcuts_groups[NUMBER_OF_SC_GROUPS];

guint8 shortcuts_cnt;
gint8 groups_cnt = -1;

shortcuts_window = g_object_new (GTK_TYPE_SHORTCUTS_WINDOW, "modal", TRUE, 
                                                            "resizable", TRUE, 
                                                            "gravity", GDK_GRAVITY_CENTER, 
                                                             NULL);

shortcuts_section = g_object_new (GTK_TYPE_SHORTCUTS_SECTION, "visible", TRUE, "max-height", 12, NULL);
gtk_container_add (GTK_CONTAINER (shortcuts_window), GTK_WIDGET (shortcuts_section));

for (shortcuts_cnt = 0; shortcuts_cnt < number_of_shortcuts; shortcuts_cnt++) {
    if (!(accels[shortcuts_cnt][0] == '<')) {
        groups_cnt++;
        shortcuts_groups[groups_cnt] = g_object_new (GTK_TYPE_SHORTCUTS_GROUP, "title", accel_txts[shortcuts_cnt], NULL);
        gtk_container_add (GTK_CONTAINER (shortcuts_section), GTK_WIDGET (shortcuts_groups[groups_cnt]));
    }
    else {      
        gtk_container_add (GTK_CONTAINER (shortcuts_groups[groups_cnt]), 
                           GTK_WIDGET (g_object_new (GTK_TYPE_SHORTCUTS_SHORTCUT, 
                                                     "accelerator", accels[shortcuts_cnt], 
                                                     "title", accel_txts[shortcuts_cnt], 
                                                     NULL)));
    }
}

gtk_window_set_transient_for (GTK_WINDOW (shortcuts_window), GTK_WINDOW (window));

gtk_widget_show_all (GTK_WIDGET (shortcuts_window));

我在 GTK 的 bugzilla 中找到了解决此问题的提示。上面的代码有两处需要修改:

  1. 部分必须添加到快捷方式 window 只有在快捷方式组被添加到它们之后。
  2. 其中一个部分必须先显示,然后才能将其添加到快捷方式 window。您无法通过阅读文档自己找到它;为此,我不得不咨询 bugzilla。

以下代码包含两组,每组有一个快捷方式:

enum { FILE_HNDL_GRP, HELP_GRP, NUMBER_OF_SC_GROUPS };

GtkShortcutsWindow *shortcuts_window;
GtkShortcutsSection *shortcuts_section;
GtkShortcutsGroup *shortcuts_groups[NUMBER_OF_SC_GROUPS];

// shortcut_window_elements
char *sc_win_elm[] = { "File Handling", 
                           "<ctrl>N | Create a new menu", 
                        "Help", 
                            "<shift><ctrl>A | About"
                     };

gchar **tokens;
guint8 num_of_sc_win_elm = sizeof (sc_win_elm) / sizeof (sc_win_elm[0]); // number_of_shortcut_window_elements

guint8 sc_win_elm_cnt; // shortcut_window_element_counter
gint8 groups_cnt = -1;

shortcuts_window = g_object_new (GTK_TYPE_SHORTCUTS_WINDOW, "modal", TRUE, 
                                                            "resizable", TRUE, 
                                                            "gravity", GDK_GRAVITY_CENTER, 
                                                            "transient-for", window, 
                                                            NULL);

shortcuts_section = g_object_new (GTK_TYPE_SHORTCUTS_SECTION, "visible", TRUE, "max-height", 12, NULL);
gtk_widget_show (GTK_WIDGET (shortcuts_section));

// Add shortcut groups and shortcuts.

for (sc_win_elm_cnt = 0; sc_win_elm_cnt < num_of_sc_win_elm; sc_win_elm_cnt++) {
    if (!(strstr (sc_win_elm[sc_win_elm_cnt], "|"))) {       
        groups_cnt++;
        shortcuts_groups[groups_cnt] = g_object_new (GTK_TYPE_SHORTCUTS_GROUP, "title", sc_win_elm[sc_win_elm_cnt], NULL);
        gtk_container_add (GTK_CONTAINER (shortcuts_section), GTK_WIDGET (shortcuts_groups[groups_cnt]));
    }
    else {
        enum { ACCEL, ACCEL_TXT };
        tokens = g_strsplit (sc_win_elm[sc_win_elm_cnt], " | ", -1);

        gtk_container_add (GTK_CONTAINER (shortcuts_groups[groups_cnt]), 
                           GTK_WIDGET (g_object_new (GTK_TYPE_SHORTCUTS_SHORTCUT, 
                                                     "accelerator", tokens[ACCEL], 
                                                     "title", tokens[ACCEL_TXT], 
                                                     NULL)));

        g_strfreev (tokens);
    }
}

gtk_container_add (GTK_CONTAINER (shortcuts_window), GTK_WIDGET (shortcuts_section)); 

gtk_widget_show_all (GTK_WIDGET (shortcuts_window));