Настройка
Это (пример) GUI ситуация:
- Окно
- GtkEntry
- Меню
- MenuItem (ускоритель: backspace )
Я использую gtk_window_add_accel_group
и gtk_widget_add_accelerator
для настройки ускорителя.
Проблема
Когда я нажимаю Backspace в пределах GtkEntry
, акселератор активируется.
Goal
Goal Для этого примера
Если в GtkEntry есть удар на обратную клавишу, он должен действовать как обычно и удалять персонажа. Если любой другой виджет сфокусирован, ускоритель должен активироваться.
Цель в целом
Цель состоит в том, чтобы иметь поведение, при котором локальные виджеты имеют более высокий приоритет относительно ввода, чем глобальные виджеты. Местные означает "сосредоточены" или их родители. Например,
- Окно
- Виджет1
- Виджет2
- Виджет3
- GtkEntry (в фокусе)
Цепочка распространения для ввода должна быть:
GtkEntry, Widget3, Widget2, Widget1, Window.
Относительно ответов
- Я знаю, что вы можете отключить указанную группу c ускорителей. Но это не приемлемое решение. Общая причина - чистота кода. Конкретные причины приведены ниже.
- GtkEntry должен знать о функциональности, которая не входит в его компетенцию.
- Если имеется много групп ускорителей, все они должны быть отключены и повторно подключены.
- Если ускорители определяются пользователем, даже неясно, какие группы ускорителей необходимо отключить.
- Если это невозможно с помощью gtk, я также буду признателен за эту информацию.
Код
Ниже приведен полный код .
#include <gdk/gdkkeysyms.h>
#include <gtk/gtk.h>
int main(int argc, char *argv[]) {
gtk_init(&argc, &argv);
// ======= setup window generalls =====
GtkWindow *window = (GtkWindow*)gtk_window_new(GTK_WINDOW_TOPLEVEL);
// ======= create vertical layout =======
GtkWidget *vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0);
gtk_container_add(GTK_CONTAINER(window),vbox);
// ======= create GtkEntry =======
gtk_box_pack_start(GTK_BOX(vbox), (GtkWidget*)gtk_entry_new(), FALSE, FALSE, 0);
// ======= create menu bar =======
{
GtkMenu *menubar = (GtkMenu*)gtk_menu_bar_new();
gtk_box_pack_start(GTK_BOX(vbox), (GtkWidget*)menubar, FALSE, FALSE, 0);
// create a new menu item in menu bar
GtkMenuItem *menuTitle = (GtkMenuItem *)gtk_menu_item_new_with_label("MenuBarItem");
gtk_menu_shell_append(GTK_MENU_SHELL(menubar), (GtkWidget*)menuTitle);
{
// create a new dropdown menu
GtkMenu *menu = (GtkMenu *)gtk_menu_new();
gtk_menu_item_set_submenu(menuTitle,(GtkWidget*)menu);
{
GtkWidget *menuItem4 = gtk_menu_item_new_with_label("Quit");
gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuItem4);
g_signal_connect(menuItem4, "activate", G_CALLBACK(gtk_main_quit), NULL);
GtkAccelGroup *accelGroup = gtk_accel_group_new();
gtk_window_add_accel_group(GTK_WINDOW(window), accelGroup);
gtk_widget_add_accelerator(menuItem4, "activate", accelGroup,
GDK_KEY_BackSpace , (GdkModifierType)0, GTK_ACCEL_VISIBLE);
}
}
}
gtk_widget_show_all ((GtkWidget*)window);
gtk_main();
return 0;
}