【问题标题】:Accelerator not displayed in GtkCheckMenuItemGtkCheckMenuItem 中未显示加速器
【发布时间】:2017-04-12 17:05:03
【问题描述】:

我目前对 GTK+3 中的菜单栏很感兴趣。 到目前为止,我有一些 CheckMenuItems 带有一个标签和一个显示的快捷键:

GtkWidget *create_menubar(void)
{
  GtkWidget *menubar = gtk_menu_bar_new();
  const static guint num_keys[] = {GDK_KEY_1, GDK_KEY_2, GDK_KEY_3, GDK_KEY_4, GDK_KEY_5, GDK_KEY_6, GDK_KEY_7, GDK_KEY_8, GDK_KEY_9, GDK_KEY_0};

  // Create a GtkAccelGroup and add it to the window.
  GtkAccelGroup *accel_group = gtk_accel_group_new();
  gtk_window_add_accel_group(GTK_WINDOW(window_main), accel_group);

  // submenu show colors
  GtkWidget *colors_Mi    = gtk_menu_item_new_with_label("colors");
  GtkWidget *colors_Menu  = gtk_menu_new();

  gtk_menu_shell_append(GTK_MENU_SHELL(menubar), colors_Mi);
  gtk_menu_item_set_submenu(GTK_MENU_ITEM(colors_Mi), colors_Menu);

  for (int i = 0; i < NUM_COLORS; i++)
  {
    char name[10];
    sprintf(name, "col %d", i+1);

// <<<<<<<<<<<<<<<<< cut mark...
    GtkWidget *show_color_Mi = gtk_check_menu_item_new_with_label(name);
// <<<<<<<<<<<<<<<<< cut mark...

    gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(show_color_Mi), show_color[i]);
    if (i < 10)
    {
      gtk_widget_add_accelerator(show_color_Mi, "activate", accel_group, num_keys[i], GDK_MOD1_MASK, GTK_ACCEL_VISIBLE);
    }
    gtk_menu_shell_append(GTK_MENU_SHELL(colors_Menu), show_color_Mi);
    g_signal_connect(G_OBJECT(show_color_Mi), "toggled", G_CALLBACK(on_menu_show_colors_toggled), &show_color[i]);
  }
  return menubar;
}

到目前为止,这工作正常。 该程序以不同颜色显示多组数据。 此菜单中的条目用于启用或禁用一组数据。 现在我想添加一些指示,以哪种颜色绘制哪组数据。

为此,我更改了 MenuItem 的创建。 现在我创建一个水平框,其中包含图像和标签。

切割标记之间的线(

// <<<<<<<<<<<<<<<<<
    GtkWidget *show_color_Mi = gtk_check_menu_item_new();

    GtkWidget *menubox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 2);
    GtkWidget *image = gtk_image_new();
    GtkWidget *menulabel = gtk_label_new(name);

    cairo_surface_t *surface = cairo_image_surface_create(CAIRO_FORMAT_RGB24, 20, 15);
    cairo_t *cr = cairo_create(surface);
    cairo_set_source_rgb(cr, colors[i].r, colors[i].g, colors[i].b);
    cairo_paint(cr);
    cairo_destroy(cr);
    gtk_image_set_from_surface(GTK_IMAGE(image), surface);

    gtk_container_add(GTK_CONTAINER(show_color_Mi), menubox);
    gtk_box_pack_start(GTK_BOX(menubox), image, FALSE, FALSE, 0);
    gtk_box_pack_start(GTK_BOX(menubox), menulabel, FALSE, FALSE, 0);
// <<<<<<<<<<<<<<<<<

现在我有了 CheckMenuItems,其中包含一个彩色矩形和与更改前相同的文本。这是好事...

糟糕的是,由于某种原因,加速键不再显示。

有什么建议我在那里做错了吗?

编辑:

根据 José Fonte 的回答进行了更新,一般来说它是有效的。 但与此同时,我发现了其他一些奇怪的效果。我正在一些带有 XFCE 的 Ubuntu 14.04 机器上运行我的程序,它按预期工作。我还在 VirtualBox 的 Ubuntu 16.04 中运行它,它也运行良好。但是在 VmWare 中的另一台 Ubuntu 14.04 机器上表现不同。缺少彩色矩形,但即使我使用了不正确的标签类型,也会显示加速键。这有点奇怪......

现在我检查了它在哪台机器上运行以及安装了哪个版本的 libgtk-3-bin:

Ubuntu 16.04(虚拟盒子) 3.18.9-1ubuntu3.1 好的

Raspbian Jessie(树莓派) 3.14.5-1+deb8u1rpi1rpig 好的

Ubuntu 14.04,XFCE(本机) 3.10.8-0ubuntu1.6 好的

Ubuntu 14.04, Unity (VmWare) 3.10.8-0ubuntu1.6 失败

【问题讨论】:

    标签: c gtk3


    【解决方案1】:

    您的问题是您使用的是普通的 GtkLabel 而不是 GtkAccelLabel。

    您必须更改为如下所示:

    [stuff deleted]
       ...
    GtkWidget *menulabel = gtk_accel_label_new(name);
    gtk_accel_label_set_accel_widget(GTK_ACCEL_LABEL(menulabel), show_color_Mi);
       ...
    gtk_box_pack_start(GTK_BOX(menubox), menulabel, TRUE, TRUE, 0);
    

    结论:使用 gtk_accel_label 而不是 gtk_label,然后设置应该是包含它的菜单项的 accel 小部件,并更改 gtk_box_pack_start 上的填充和展开标志以允许额外空间。这应该可以解决您的问题。

    【讨论】:

    • 非常感谢这个提示!它真的很有帮助。但它也会引起一些混乱。我的印象是加速器是菜单项的一项功能,而不是其封闭元素的一项功能。如果我做对了,我总是需要一个标签。如果我只想要没有任何文本的彩色矩形,我仍然需要一个 accel_label 来指示加速器。这对我来说有点意外......
    • 你是对的,但如果你想要加速器的文本表示,那么你需要一个标签,在这种特殊情况下,一个 accel_label。
    • 同时我发现了一些其他奇怪的效果。我正在一些带有 XFCE 的 Ubuntu 14.04 机器上运行我的程序,它按预期工作。我还在 VirtualBox 的 Ubuntu 16.04 中运行它,它也运行良好。但是在 VmWare 中的另一台 Ubuntu 14.04 机器上表现不同。缺少彩色矩形,但即使我使用了不正确的标签类型,也会显示加速键。这有点奇怪......
    • 嗯,可能与主题 css 相关。检查你的 vbox 并给它均匀的大小,就像测试一样,以确保你有空间分配给图像。还要检查发行版使用的 Gtk+ 版本。
    • 嗨@Gerhardh,来自documentation:“请注意,使用 gtk_menu_item_new_with_label()(或 GtkCheckMenuItem 和 GtkRadioMenuItem 的类似函数之一)创建 GtkMenuItem 会自动将 GtkAccelLabel 添加到 GtkMenuItem 并调用 gtk_accel_label_set_accel_widget () 为您设置它。”。因此,当您创建带有标签的 check_menu_item 时,会自动创建一个 accell_label,如果您实现它,那么您必须自己完成。看不到普通标签是如何发生的。代码正确吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-09-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-12-18
    相关资源
    最近更新 更多