问题
I'm trying to implement the Ctrl+C shortcut a widget without it disturbing other defined shortcuts.
Problem
My window looks like this:
GtkWindow
GtkEntry
GtkToggleButton
Part of the code
// --- add checkbox ---
GtkWidget * checkbutton = gtk_check_button_new_with_label("My Checkbox");
gtk_container_add(GTK_CONTAINER(vbox), GTK_WIDGET(checkbutton));
// --- setup checkbox shortcut ---
GtkAccelGroup * accel_group = gtk_accel_group_new();
gtk_window_add_accel_group(GTK_WINDOW(window), accel_group);
gtk_widget_add_accelerator(checkbutton, "clicked", accel_group,
GDK_KEY_c, GDK_CONTROL_MASK, GTK_ACCEL_VISIBLE);
g_signal_connect(checkbutton, "clicked", G_CALLBACK(onCopyCheckbox), NULL);
// problem: this event fires, even if GtkEntry is focussed
// it then block the <kbd>Ctrl+C</kbd>-Event of GtkEntry
Expected behaviour
- If
GtkEntry
is focussed and Ctrl+C is pressed, the function callback1() should be triggered. - If
GtkToggleButton
is focussed and Ctrl+C is pressed, it should print "onCopyCheckbox() called\n".
Actual behavior
- If
GtkEntry
is focussed and Ctrl+C is pressed, "onCopyCheckbox() called\n" gets printed and nothing gets copied. - If
GtkToggleButton
is focussed and Ctrl+C is pressed, "onCopyCheckbox() called\n" gets printed.
Please do not...
- tell me I should use a different shortcut / accelerator.
Full compilable and executable code:
#include <gtk/gtk.h>
#include <gdk/gdkkeysyms.h>
// ------------------------------------------------------------
void
onCopyCheckbox (GtkWidget *widget,
GdkDragContext *context,
gpointer user_data)
{
printf("onCopyCheckbox() called\n");
}
// ------------------------------------------------------------
void fillWindow (GtkWindow * window)
{
// ------- create layout ------------
GtkWidget *vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0);
gtk_container_add(GTK_CONTAINER(window),GTK_WIDGET(vbox));
// --- add line edit ---
GtkWidget * lineedit = gtk_entry_new();
gtk_container_add(GTK_CONTAINER(vbox), GTK_WIDGET(lineedit));
// --- add checkbox ---
GtkWidget * checkbutton = gtk_check_button_new_with_label("My Checkbox");
gtk_container_add(GTK_CONTAINER(vbox), GTK_WIDGET(checkbutton));
// --- setup checkbox shortcut ---
GtkAccelGroup * accel_group = gtk_accel_group_new();
gtk_window_add_accel_group(GTK_WINDOW(window), accel_group);
gtk_widget_add_accelerator(checkbutton, "clicked", accel_group,
GDK_KEY_c, GDK_CONTROL_MASK, GTK_ACCEL_VISIBLE);
g_signal_connect(checkbutton, "clicked", G_CALLBACK(onCopyCheckbox), NULL);
// problem: this event fires, even if GtkEntry is focussed
// it then block the <kbd>Ctrl+C</kbd>-Event of GtkEntry
}
// ------------------------------------------------------------
int main(int argc, char *argv[]) {
gtk_init(&argc, &argv);
GtkWindow * window;
{
window = (GtkWindow*)gtk_window_new(GTK_WINDOW_TOPLEVEL);
gtk_window_set_title (window, "Window title");
gtk_window_set_default_size (window, 200, 200);
g_signal_connect(window, "destroy", gtk_main_quit, NULL);
}
fillWindow(window);
gtk_widget_show_all ((GtkWidget*)window);
gtk_main();
return 0;
}
// ------------------------------------------------------------
回答1:
Imagine you want to spawn the function below on Ctrl+C while the checkbox is focussed.
void
shortcutAction(GSimpleAction* a, GVariant * b, gpointer c){
printf("shortcutAction() called\n");
}
This is how you setup your checkbox
// --- add checkbox ---
GtkWidget * checkbox = gtk_check_button_new_with_label("My Checkbox");
gtk_container_add(GTK_CONTAINER(vbox), GTK_WIDGET(checkbox));
// ========= setup checkbox shortcut ==============
GtkApplication * app = GTK_APPLICATION(g_application_get_default());
// ------- Part 1: create the action itself -----------
// All the action you want to add go in one ActionGroup
GSimpleActionGroup * group = g_simple_action_group_new();
// define all action you want to have
// these action can be basically seen as some kind of signal
static const GActionEntry actions[] {
{ .name="print", .activate=shortcutAction}
};
// ActionGroup.add(actions[])
g_action_map_add_action_entries(G_ACTION_MAP(group), actions, G_N_ELEMENTS(actions), NULL);
// Widget.addActionGroup(ActionGroup) // connect widget and action group
// No you also create a name for the group. Here "checkbox" (but can be anything)
gtk_widget_insert_action_group (GTK_WIDGET(checkbox), "checkbox", G_ACTION_GROUP(group));
// ------- Part 2: create the shortcut to create the action --------
const gchar * const shortcuts[] = { "<Ctrl>C", NULL };
gtk_application_set_accels_for_action (app, "checkbox.print", shortcuts);
Remarks
As you see in the code, there's a strict difference between
- defining actions
- defining shortcuts
来源:https://stackoverflow.com/questions/61368448/implementing-overlapping-shortcuts