实现重叠快捷方式
Implementing overlapping shortcuts
我正在尝试实现 Ctrl+C 快捷方式小部件,而不会干扰其他已定义的快捷方式。
问题
我的 window 看起来像这样:
GtkWindow
GtkEntry
GtkToggleButton
部分代码
// --- 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
预期行为
- 如果
GtkEntry
获得焦点并按下 Ctrl+C,则应触发函数 callback1()。
- 如果聚焦
GtkToggleButton
并按下 Ctrl+C,它应该打印 "onCopyCheckbox() called\n".
实际行为
- 如果
GtkEntry
获得焦点并按下 Ctrl+C,则打印 "onCopyCheckbox() called\n" 并且不会复制任何内容。
- 如果
GtkToggleButton
获得焦点并按下 Ctrl+C,则打印 "onCopyCheckbox() called\n"。
请不要...
- 告诉我应该使用不同的快捷方式/加速器。
完整的可编译和可执行代码:
#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;
}
// ------------------------------------------------------------
假设您想在选中复选框时按 Ctrl+C 生成下面的函数。
void
shortcutAction(GSimpleAction* a, GVariant * b, gpointer c){
printf("shortcutAction() called\n");
}
这就是您设置复选框的方式
// --- 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);
备注
正如您在代码中看到的,
之间存在严格的区别
- 定义动作
- 定义快捷方式
我正在尝试实现 Ctrl+C 快捷方式小部件,而不会干扰其他已定义的快捷方式。
问题
我的 window 看起来像这样:
GtkWindow
GtkEntry
GtkToggleButton
部分代码
// --- 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
预期行为
- 如果
GtkEntry
获得焦点并按下 Ctrl+C,则应触发函数 callback1()。 - 如果聚焦
GtkToggleButton
并按下 Ctrl+C,它应该打印 "onCopyCheckbox() called\n".
实际行为
- 如果
GtkEntry
获得焦点并按下 Ctrl+C,则打印 "onCopyCheckbox() called\n" 并且不会复制任何内容。 - 如果
GtkToggleButton
获得焦点并按下 Ctrl+C,则打印 "onCopyCheckbox() called\n"。
请不要...
- 告诉我应该使用不同的快捷方式/加速器。
完整的可编译和可执行代码:
#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;
}
// ------------------------------------------------------------
假设您想在选中复选框时按 Ctrl+C 生成下面的函数。
void
shortcutAction(GSimpleAction* a, GVariant * b, gpointer c){
printf("shortcutAction() called\n");
}
这就是您设置复选框的方式
// --- 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);
备注
正如您在代码中看到的,
之间存在严格的区别- 定义动作
- 定义快捷方式