1

我正在尝试在 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,它表明当我按 时Ctrlevent->state文档中的 20 而不是 4 或 1 << 2。如果我将其更改GDK_CONTROL_MASK为 20,它适用于较新的系统,但不适用于旧系统。有人请告诉我为什么会发生这种情况以及如何解决它。

4

2 回答 2

3

event->state是一个位图,这意味着值 20 并不意味着“20 而不是 4”,而是“同时 4 和 16”。根据标题,值 16 ( 1 << 4) 对应于MOD2修饰符,它可能对应fn于笔记本电脑上的键。

一个简单的解决方法是使用&运算符来检查控制,同时忽略其他修饰符:

    if (event->state & GDK_CONTROL_MASK && event->keyval == 'd')

这将适用于两个系统。

于 2013-04-26T12:42:50.243 回答
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')
    ...
于 2017-10-03T17:52:42.207 回答