我在linux中有一个全局键事件处理程序,如下所示。我需要知道要抓住哪个键盘。例如,如果按键“ P”被按下,我得到相应的按键代码。有什么办法可以从这个未签名的键码中获得键名(“ P”)?

#include <xcb/xcb.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>

#include <QtX11Extras/QX11Info>

void EventFilter::setup(QWidget *target)
{
    this->target = target;

    Display * display = QX11Info::display();
    unsigned int modifiers = ControlMask;
    keycode = XKeysymToKeycode(display, XK_A);
    XGrabKey(display, keycode, modifiers, DefaultRootWindow(display), 1, GrabModeAsync, GrabModeAsync);
}

bool EventFilter::nativeEventFilter(const QByteArray &eventType, void *message, long *)
{
    if (eventType == "xcb_generic_event_t")
    {
        xcb_generic_event_t* xcbevent = static_cast<xcb_generic_event_t *>(message);

        switch(xcbevent->response_type)
        {
        case XCB_KEY_PRESS:
            xcb_key_press_event_t * keypress_event = static_cast<xcb_key_press_event_t *>(message);
            if(keypress_event->state & XCB_MOD_MASK_CONTROL)
            {
                if(keypress_event->detail == keycode)
                {
                    //print key name here
                }
            }
        }
    }
   return false;
 }

最佳答案

给定键码,可以从事件detail字段中使用KeySym函数获取XkbKeycodeToKeysym,然后使用按下键的文本表示形式,将KeySym传递给XKeysymToString函数。

包括以下内容:

#include <X11/XKBlib.h>


然后,在事件处理程序中:

case XCB_KEY_PRESS:
    xcb_key_press_event_t * keypress_event = static_cast<xcb_key_press_event_t *>(message);
    xcb_keycode_t code = keypress_event->detail;
    qDebug() << XKeysymToString( XkbKeycodeToKeysym(QX11Info::display(), code, 0, 0) );


在上面的示例中,将索引0作为XkbKeycodeToKeysym的最后一个参数传递。这将返回已按下键的符号,就好像未按下Shift键(或大写锁定或任何其他修饰键)一样。传递索引1将返回符号,就像按下Shift键一样。其他值(例如2)会产生一个符号,可以通过按下更多的修饰键来获得符号(例如,在我的意大利语键盘中,我必须按Alt Gr键入方括号)。

请注意,返回的字符串实际上是用于标识键盘符号的名称,例如对于字母来说可以是abcX,但是可以是commabackslash其他符号。

关于c++ - 从键码(X11 XGrabKey)获取键名,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/49491918/

10-12 00:13