【问题标题】:GTK: "key-press-event" handling while Shift is pressedGTK:按下 Shift 时的“按键事件”处理
【发布时间】:2017-11-22 06:11:45
【问题描述】:

我正在编写一个小程序:它是一个单独的下拉菜单,以小写字母作为菜单项标签:

如果您持有Shift,则标签变为大写(我为此编写了“key-press-event”和“key-release-event”处理程序)。问题是,当按下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+EnterShift+ 箭头键,而无需手动处理。

【问题讨论】:

    标签: c callback gtk


    【解决方案1】:

    我终于找到了选择菜单项(“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;
    ...
    

    这几乎回答了我的问题。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2022-11-28
      • 1970-01-01
      • 1970-01-01
      • 2021-02-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-12-04
      相关资源
      最近更新 更多