2017-11-22 7 views
0

私は小さなプログラムを書いている:メニュー項目がラベルとして、それは小文字で唯一のドロップダウンメニューです:GTK:「キープレスイベント」取扱Shiftキーが押されている間

enter image description here

あなたの場合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+EnterShift +矢印キーを手作業で処理する必要なく同じ方法で処理します。

答えて

0

私は最終的にmenuitems( "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; 
... 

これはかなり私の質問に答えるものです。

関連する問題