'Accelerator on a Gtk.Button without a label?

So I have a Gtk.Button. I want to add a accelator (shortcut key), such as Ctrl+O.

If I had a label, I could use a underscore under the letter to bind, such as "_Open".

My button doesn't have any label though, it has a icon. It is a button I have in my Gtk.HeaderBar.

How do I place a accelerator on a Gtk.Button with a icon but no label?



Solution 1:[1]

If using XML then add a <accelerator> element to the object.

<object class="GtkButton" id="foo_button">
  <property name="visible">1</property>
  <property name="can-focus">1</property>
  <signal name="clicked" handler="_on_foo_button_clicked" swapped="no"/>
  <accelerator key="n" signal="activate" modifiers="GDK_CONTROL_MASK"/>
  <child>
    <object class="GtkImage">
      <property name="visible">1</property>
      <property name="icon-name">folder-new-symbolic</property>
    </object>
  </child>
</object>

Solution 2:[2]

i think accelerators are used for Menu items, but you can set an underscore mnemonic such as "_Open", with Gtk.Button.new_with_mnemonic(label)

Solution 3:[3]

When setting an accelerator/shortcut via c-API, I found the following solution:

/* init the keyboard shortcuts */
{
#if ( GTK_MAJOR_VERSION >= 4 )
    (*this_).keyboard_shortcut_ctrl = GTK_SHORTCUT_CONTROLLER(gtk_shortcut_controller_new());
    gtk_widget_add_controller( (*this_).window, GTK_EVENT_CONTROLLER((*this_).keyboard_shortcut_ctrl) );
#else
    (*this_).keyboard_shortcut_group = gtk_accel_group_new();
    gtk_window_add_accel_group(GTK_WINDOW( (*this_).window ), (*this_).keyboard_shortcut_group);
#endif
}

An then for each button:

    (*this_).edit_undo_icon = gtk_image_new_from_pixbuf( gui_resources_get_edit_undo( res ));
    gtk_widget_set_size_request( GTK_WIDGET((*this_).edit_undo_icon), 32 /*=w*/ , 32 /*=h*/ );
    (*this_).edit_undo = GTK_BUTTON(gtk_button_new());
    gtk_button_set_image( GTK_BUTTON((*this_).edit_undo), (*this_).edit_undo_icon );
    gtk_widget_set_tooltip_text( GTK_WIDGET((*this_).edit_undo), "Undo (Ctrl-Z)" );
#if ( GTK_MAJOR_VERSION >= 4 )
    GtkShortcutTrigger *undo_trig = gtk_shortcut_trigger_parse_string( "<Control>Z" );
    GtkShortcutAction *undo_act = gtk_callback_action_new( &gui_toolbox_undo_shortcut_callback,
                                                           &((*this_).tools_data),
                                                           NULL
                                                         );
    GtkShortcut* ctrl_z = gtk_shortcut_new_with_arguments( undo_trig,
                                                           undo_act,
                                                           NULL /* = format_string */
                                                         );
    gtk_shortcut_controller_add_shortcut( (*this_).keyboard_shortcut_ctrl, ctrl_z );
#else
    gtk_widget_add_accelerator( GTK_WIDGET((*this_).edit_undo),
                                "clicked",
                                (*this_).keyboard_shortcut_group,
                                GDK_KEY_z,
                                GDK_CONTROL_MASK,
                                GTK_ACCEL_VISIBLE
                              );

#endif

Note, that the gui_toolbox_undo_shortcut_callback has a different signature then the button-clicked signal.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Fred
Solution 2
Solution 3 Andi Warnke