子菜单级别的 GtkMenu 无法在 ubuntu 20.04 中引发“活动”信号

Posted

技术标签:

【中文标题】子菜单级别的 GtkMenu 无法在 ubuntu 20.04 中引发“活动”信号【英文标题】:GtkMenu in Sub-menu level cannot raise 'active' signal in ubuntu 20.04 【发布时间】:2021-07-10 07:56:29 【问题描述】:

最近,我将代码从 ubuntu 14.04 升级到 20.04。 UI 似乎工作正常,但带有触摸面板的子菜单。 我按下菜单并选择 menuitem2 并显示子菜单, 当我点击触摸屏打开子菜单时,它没有响应。

我编写了一个代码进行检查,发现当我点击触摸屏时发送了“选择”信号而不是“活动”信号。 (使用鼠标单击时代码工作正常) 有人可以帮我解决这个问题吗?或者有任何其他 GtkWidget 可以用来代替 GtkMenu?

任何 cmets 和建议将不胜感激。

Brlow 是我的代码:

/* 
 * Build:
 * gcc $(pkg-config --cflags gtk+-3.0) popover_sample.c -o popover_sample $(pkg-config --libs gtk+-3.0)
 */

#include <stddef.h>
#include <gtk/gtk.h>


void on_ITEM2_activate(GtkMenuItem* button, gpointer user_data)

    printf("on_ITEM2_activate \n");


void on_SEC_2_activate(GtkMenuItem* button, gpointer user_data)

    printf("on_SEC_2_activate \n");



void on_SEC_1_activate(GtkMenuItem* button, gpointer user_data)

    printf("on_SEC_1_activate \n");


void on_submenuitem1_activate(GtkMenuItem* button, gpointer user_data)

    printf("on_submenuitem1_activate \n");


void on_submenuitem2_activate(GtkMenuItem* button, gpointer user_data)

    printf("on_submenuitem2_activate \n");



void on_submenuitem3_activate(GtkMenuItem* button, gpointer user_data)

    printf("on_submenuitem3_activate \n");


void on_submenuitem4_activate(GtkMenuItem* button, gpointer user_data)

    printf("on_submenuitem4_activate \n");



// called when window is closed
void on_QUIT_BTN_clicked()

    gtk_main_quit();



void on_btn1_clicked(GtkMenuItem* button, gpointer user_data)

    gtk_main_quit();


void on_ITEM1_activate(GtkMenuItem* button, gpointer user_data)

    GtkWidget *open_item;   // New menuitem
    GtkWidget *save_item;   // New menuitem
    GtkWidget *quit_item;   // New menuitem
    GtkWidget *sep;      // New sep
    GtkWidget *ITEM1_Menu;  // New menu

    ITEM1_Menu = gtk_menu_new();

    open_item = gtk_menu_item_new_with_label ("Open");
    save_item = gtk_menu_item_new_with_label ("Save");
    quit_item = gtk_menu_item_new_with_label ("Quit");
    sep = gtk_separator_menu_item_new();

    gtk_menu_item_set_submenu(GTK_MENU_ITEM(button), ITEM1_Menu);
    gtk_menu_shell_append(GTK_MENU_SHELL(ITEM1_Menu), open_item);
    gtk_menu_shell_append(GTK_MENU_SHELL(ITEM1_Menu), save_item);
    gtk_menu_shell_append(GTK_MENU_SHELL(ITEM1_Menu), sep);
    gtk_menu_shell_append(GTK_MENU_SHELL(ITEM1_Menu), quit_item);


    g_signal_connect_swapped (G_OBJECT (open_item), "activate",
                              G_CALLBACK (on_submenuitem1_activate),
                              NULL);
    g_signal_connect_swapped (G_OBJECT (save_item), "activate",
                              G_CALLBACK (on_submenuitem2_activate),
                              NULL);

    g_signal_connect_swapped (G_OBJECT (quit_item), "activate",
                              G_CALLBACK (on_QUIT_BTN_clicked),
                              NULL);

    gtk_widget_show (open_item);
    gtk_widget_show (save_item);
    gtk_widget_show (quit_item);
    gtk_widget_show (sep);

    printf("on_ITEM1_activate \n");




int main(int argc, char *argv[])

    GtkBuilder      *builder;
    GtkWidget       *window;
    GError *error = NULL;

    gtk_init(&argc, &argv);

    builder = gtk_builder_new();

    if (gtk_builder_add_from_file (builder, "Menu_Test.glade", &error) == 0)
    
        printf("Unable to open file named \"Menu_Test.glade\" \n");
        return 1;
    

    window = GTK_WIDGET(gtk_builder_get_object(builder, "test_win"));
    if (NULL == window)
    
        printf("Unable to file object with id \"test_win\" \n");
    

    g_signal_connect (window, "destroy", G_CALLBACK (gtk_main_quit), NULL);
    window = GTK_WIDGET(gtk_builder_get_object(builder, "test_win"));
    

    gtk_builder_connect_signals(builder, NULL);
    g_object_unref(builder);
    gtk_widget_show_all(window);
    gtk_main();

    return 0;

和下面的空地:

<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.38.2 -->
<interface>
  <requires lib="gtk+" version="3.24"/>
  <object class="GtkMenu" id="menu1">
    <property name="visible">True</property>
    <property name="can-focus">False</property>
    <child>
      <object class="GtkMenuItem" id="menuitem1">
        <property name="visible">True</property>
        <property name="can-focus">False</property>
        <property name="tooltip-text" translatable="yes">ITEM_1</property>
        <property name="label" translatable="yes">menuitem1</property>
        <property name="use-underline">True</property>
        <signal name="select" handler="on_ITEM1_activate" swapped="no"/>
      </object>
    </child>
    <child>
      <object class="GtkMenuItem" id="menuitem2">
        <property name="visible">True</property>
        <property name="can-focus">False</property>
        <property name="tooltip-text" translatable="yes">ITEM_2</property>
        <property name="label" translatable="yes">menuitem2</property>
        <property name="use-underline">True</property>
        <signal name="activate" handler="on_ITEM2_activate" swapped="no"/>
        <child type="submenu">
          <object class="GtkMenu" id="menu2">
            <property name="visible">True</property>
            <property name="can-focus">False</property>
            <child>
              <object class="GtkMenuItem" id="submenuitem3">
                <property name="visible">True</property>
                <property name="can-focus">False</property>
                <property name="tooltip-text" translatable="yes">Item_2_1</property>
                <property name="label" translatable="yes">menuitem3</property>
                <property name="use-underline">True</property>
                <signal name="activate" handler="on_submenuitem3_activate" swapped="no"/>
              </object>
            </child>
            <child>
              <object class="GtkMenuItem" id="submenuitem4">
                <property name="name">submenuitem4</property>
                <property name="visible">True</property>
                <property name="can-focus">False</property>
                <property name="tooltip-text" translatable="yes">Item_2_2</property>
                <property name="label" translatable="yes">menuitem4</property>
                <property name="use-underline">True</property>
                <signal name="activate" handler="on_submenuitem4_activate" swapped="no"/>
              </object>
            </child>
          </object>
        </child>
      </object>
    </child>
  </object>
  <object class="GtkWindow" id="test_win">
    <property name="width-request">300</property>
    <property name="height-request">300</property>
    <property name="can-focus">False</property>
    <child>
      <object class="GtkBox" id="box1">
        <property name="visible">True</property>
        <property name="can-focus">False</property>
        <property name="orientation">vertical</property>
        <property name="spacing">76</property>
        <child>
          <object class="GtkMenuButton" id="menubutton1">
            <property name="visible">True</property>
            <property name="can-focus">True</property>
            <property name="receives-default">True</property>
            <property name="popup">menu1</property>
            <child>
              <placeholder/>
            </child>
          </object>
          <packing>
            <property name="expand">False</property>
            <property name="fill">True</property>
            <property name="position">0</property>
          </packing>
        </child>
        <child>
          <placeholder/>
        </child>
        <child>
          <object class="GtkButton" id="button1">
            <property name="label" translatable="yes">button</property>
            <property name="visible">True</property>
            <property name="can-focus">True</property>
            <property name="receives-default">True</property>
            <property name="halign">center</property>
            <property name="valign">baseline</property>
            <signal name="clicked" handler="on_QUIT_BTN_clicked" swapped="no"/>
          </object>
          <packing>
            <property name="expand">False</property>
            <property name="fill">True</property>
            <property name="position">2</property>
          </packing>
        </child>
      </object>
    </child>
  </object>
</interface>

【问题讨论】:

我缝了一个触摸屏补丁:gitlab.gnome.org/GNOME/gtk/-/merge_requests/1794 该补丁似乎与 GTK-3.24 兼容,但我使用的是 GTK-3.24.20。这仍然发生在我的触摸屏上 将 gtk lib 升级到 3.24.28 版本后。这个问题已经解决了。 【参考方案1】:

将 gtk lib 升级到 3.24.28 版本后。这个问题已经解决了。

【讨论】:

以上是关于子菜单级别的 GtkMenu 无法在 ubuntu 20.04 中引发“活动”信号的主要内容,如果未能解决你的问题,请参考以下文章

GTK+图形化应用程序开发学习笔记—菜单

在奏鸣曲管理员中,我们如何拥有多个级别的子管理员

ubuntu中没有终端怎么打开

如何在android的导航菜单中创建子级别?

Ubuntu开机黑屏无法登录

如何在VB中建一个二级菜单 并在二级菜单中添加子菜单项