我正在编写一个小程序:它是一个单独的下拉菜单,以小写字母作为菜单项标签:
如果你按住Shift
,标签就会大写(我为此编写了“按键事件”和“按键释放事件”处理程序)。问题是,当按下 Shift
时,我仍然想导航菜单并按下 Enter
来选择项目。如果按下某个修饰符,则不会触发默认处理程序,因此我按以下方式处理它:
static gboolean menu_key_event(GtkWidget *menu, GdkEvent *event, gpointer data) {
(void)data;
GdkEventKey *key_event = (GdkEventKey*)event;
switch (key_event->keyval) {
case GDK_KEY_Shift_L:
case GDK_KEY_Shift_R: ;
bool b = (key_event->type == GDK_KEY_PRESS) ? true : false;
gtk_container_foreach(GTK_CONTAINER(menu), menuitem_capitalize_label, &b);
return TRUE;
break;
case GDK_KEY_Return:
if ((key_event->type == GDK_KEY_PRESS) &&
(key_event->state & GDK_SHIFT_MASK)) {
// I want default callback to handle this
g_signal_emit_by_name(menu, "activate-current");
return TRUE;
}
break;
case GDK_KEY_Up:
case GDK_KEY_Down:
if ((key_event->type == GDK_KEY_PRESS) &&
(key_event->state & GDK_SHIFT_MASK)) {
// Some function I wrote to fiddle with menu items,
// simulating default selection behavior
menu_rotate_selection(GTK_MENU_SHELL(menu), key_event->keyval);
return TRUE;
}
break;
}
return FALSE;
}
这可以以更优雅的方式完成吗?简而言之,我希望我的应用程序以相同的方式处理 Enter
、箭头键和 Shift+Enter
、Shift
+ 箭头键,而不需要手动处理它。
最佳答案
我终于找到了选择菜单项(“move-current”)所需的信号,因此不再需要我自己的 menu_rotate_selection
函数。不过,该信号名称令人困惑,我宁愿认为其目的是在菜单中实际移动菜单项本身(首先我认为另一个名称晦涩的信号“循环焦点”是用于更改选择)。现在可以重写如下:
...
case GDK_KEY_Up:
case GDK_KEY_Down:
if ((key_event->type == GDK_KEY_PRESS) &&
(key_event->state & GDK_SHIFT_MASK)) {
GtkMenuDirectionType dir = (key_event->keyval == GDK_KEY_Up) ?
GTK_MENU_DIR_PREV : GTK_MENU_DIR_NEXT;
g_signal_emit_by_name(menu, "move-current", dir);
return TRUE;
}
break;
...
这几乎回答了我的问题。
关于c - GTK: "key-press-event"按下 Shift 时的处理,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47427928/