我正在尝试捕获用户键,在GUI窗口上按Ctrl + d退出。我的代码如下所示:
static gboolean
callback(GtkWidget *widget,
GdkEventKey *event,
gpointer data)
{
if(event->state == GDK_CONTROL_MASK && event->keyval == 'd')
gtk_main_quit();
return FASLE;
}
这适用于我的笔记本电脑(Ubuntu 11.04,gcc 4.5.2,libgtk 2.24.4)。但是当我在一个较新的系统(Ubuntu 12.10,gcc 4.7.2,libgtk 2.24.13)上做同样的事情时,它不起作用。
我在g_print("%u\n", event->state);
声明之前添加了if
,它显示当我按Ctrl
时,event->state
为20而不是4或1<< 2在文档中。如果我将GDK_CONTROL_MASK
更改为20,它适用于较新的系统,但不适用于较旧的系统。有人请告诉我为什么会发生这种情况以及如何解决这个问题。
答案 0 :(得分:3)
event->state
是bitmap,这意味着值20不表示“20而不是4”,而是“4和16同时”。根据标题,值16(1 << 4
)对应于MOD2
修饰符,它可能对应于笔记本电脑上的 fn 键。
一个简单的解决方法是使用&
运算符检查控件,同时忽略其他修饰符:
if (event->state & GDK_CONTROL_MASK && event->keyval == 'd')
可以在两个系统上运行。
答案 1 :(得分:0)
这是因为state
还包括像Caps Lock和Num Lock这样的修饰符。
解决方案记录在https://developer.gnome.org/gtk3/stable/checklist-modifiers.html:
使用gtk_accelerator_get_default_mod_mask()
获取修改器的位图,这些修改器也是加速键(Control,Alt,Shift,Super,Hyper和Meta),然后是按位和事件状态,例如:
GdkModifierType accel_mask = gtk_accelerator_get_default_mod_mask ();
if (event->state & accel_mask == GDK_CONTROL_MASK && event->keyval == 'd')
...