在简单的GTK按键事件示例中,GDK_SHIFT_MASK似乎被忽略了。

19

可以请有经验的开发者编译并执行我下面提供的简短示例代码吗?如果您能正常使用Shift键修饰符,请告诉我。该示例旨在演示在gtk中按键功能。它对于简单的按键操作效果很好,甚至可以与控制键修饰符一起工作,但不能使用Shift键修饰符。

/*
 * 
 * compile command:
 * 
 * gcc keypress3.c -o keypress3  `pkg-config --libs --cflags gtk+-2.0`
 * 
 */

#include <gtk/gtk.h>
#include <gdk/gdkkeysyms.h>

gboolean
on_key_press (GtkWidget *widget, GdkEventKey *event, gpointer user_data);

int main (int argc, char *argv[])
{
  GtkWidget *window;

  gtk_init (&argc, &argv);

  window = gtk_window_new (GTK_WINDOW_TOPLEVEL);

  g_signal_connect (G_OBJECT (window), "destroy", G_CALLBACK (gtk_main_quit), NULL);
  g_signal_connect (G_OBJECT (window), "key_press_event", G_CALLBACK (on_key_press), NULL);

  gtk_widget_show_all (window);

  gtk_main ();

  return 0;
}

gboolean
on_key_press (GtkWidget *widget, GdkEventKey *event, gpointer user_data)
{
  switch (event->keyval)
  {
    case GDK_p:
      printf("key pressed: %s\n", "p");
      break;
    case GDK_s:
      if (event->state & GDK_SHIFT_MASK)
      {
        printf("key pressed: %s\n", "shift + s");
      }
      else if (event->state & GDK_CONTROL_MASK)
      {
        printf("key pressed: %s\n", "ctrl + s");
      }
      else
      {
        printf("key pressed: %s\n", "s");
      }
      break;
    case GDK_m:
      if (event->state & GDK_SHIFT_MASK)
      {
        printf("key pressed: %s\n", "shift + m");
      }
      else if (event->state & GDK_CONTROL_MASK)
      {
        printf("key pressed: %s\n", "ctrl + m");
      }
      else
      {
        printf("key pressed: %s\n", "m");
      }
      break;

    default:
      return FALSE; 
  }

  return FALSE; 
}
我收到的输出:
key pressed: m
key pressed: ctrl + m
key pressed: p
key pressed: ctrl + s
key pressed: s

当我按下shift + s或shift + m时,什么也没有发生,因此似乎我并不太了解GDK_SHIFT_MASK应该如何使用,尽管我已经阅读了文档并看到了许多其他示例,其中它似乎被使用的方式完全相同。


你确切地得到了哪个输入才产生了那个输出? - ptomato
@ptomato 输出恰好描述了输入。 - nomadicME
2个回答

26

当按下shift+s时,event->keyval的值为GDK_S,而不是GDK_s。换句话说,GDK已经为您解释了键盘,给出了符号'S',而不是's'。尽管如此,shift掩码仍然被设置。您可以通过添加GDK_S的情况来查看这一点:

...
case GDK_S:  // add this line
case GDK_s:
  if (event->state & GDK_SHIFT_MASK)
  {
    printf("key pressed: %s\n", "shift + s");
  }
  else if (event->state & GDK_CONTROL_MASK)
  {
....

1
哎呀!这个问题困扰了我很久,但是一旦你解释了一下,它似乎变得非常明显。:) 谢谢。 - nomadicME

10

这不是一个答案,应该作为对其所回应的帖子的评论。我希望人们不要直接将SO帖子中的代码整个使用作为自己的基础...那些这样做的人会通过阅读错误和文档很快找出问题...但我可能过于乐观了。因此,这可能非常有用。但它仍然不是一个答案。 - underscore_d

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接