1.前言
最近需要qt获取按键ascii码,可是QKeyEvent::key()返回的是键码,不是ascii码(0-127),需要从键码转ascii码。遇到的问题是不知道如何获取Capslock键状态,网友说用LOBYTE(GetKeyState(VK_CAPITAL)),但如何跨平台呢,QT不该只用windows吧?
2.解决办法
用QKeyEvent::nativeModifiers()获取CapsLock键状态,
keyEvent->nativeModifiers() & CapsLock;
依据源码:
bool QKeyMapperPrivate::translateKeyEvent(QWidget *widget, const MSG &msg, bool grab) { Q_Q(QKeyMapper); Q_UNUSED(q); // Strange, but the compiler complains on q not being referenced, even if it is.. bool k0 = false; bool k1 = false; int msgType = msg.message; // WM_CHAR messages already contain the character in question so there is // no need to fiddle with our key map. In any other case add this key to the // keymap if it is not present yet. if (msg.message != WM_CHAR) updateKeyMap(msg);
const quint32 scancode = (msg.lParam >> 16) & scancodeBitmask; const quint32 vk_key = msg.wParam;
quint32 nModifiers = 0;
#if defined(Q_OS_WINCE) nModifiers |= (GetKeyState(VK_SHIFT ) < 0 ? ShiftAny : 0); nModifiers |= (GetKeyState(VK_CONTROL) < 0 ? ControlAny : 0); nModifiers |= (GetKeyState(VK_MENU ) < 0 ? AltAny : 0); nModifiers |= (GetKeyState(VK_LWIN ) < 0 ? MetaLeft : 0); nModifiers |= (GetKeyState(VK_RWIN ) < 0 ? MetaRight : 0); #else // Map native modifiers to some bit representation nModifiers |= (GetKeyState(VK_LSHIFT ) & 0x80 ? ShiftLeft : 0); nModifiers |= (GetKeyState(VK_RSHIFT ) & 0x80 ? ShiftRight : 0); nModifiers |= (GetKeyState(VK_LCONTROL) & 0x80 ? ControlLeft : 0); nModifiers |= (GetKeyState(VK_RCONTROL) & 0x80 ? ControlRight : 0); nModifiers |= (GetKeyState(VK_LMENU ) & 0x80 ? AltLeft : 0); nModifiers |= (GetKeyState(VK_RMENU ) & 0x80 ? AltRight : 0); nModifiers |= (GetKeyState(VK_LWIN ) & 0x80 ? MetaLeft : 0); nModifiers |= (GetKeyState(VK_RWIN ) & 0x80 ? MetaRight : 0); // Add Lock keys to the same bits nModifiers |= (GetKeyState(VK_CAPITAL ) & 0x01 ? CapsLock : 0); nModifiers |= (GetKeyState(VK_NUMLOCK ) & 0x01 ? NumLock : 0); nModifiers |= (GetKeyState(VK_SCROLL ) & 0x01 ? ScrollLock : 0); #endif // Q_OS_WINCE
if (msg.lParam & ExtendedKey) nModifiers |= msg.lParam & ExtendedKey;
3. 总结
QKeyEvent::key() 返回虚拟键码,比如Qt::Key_Space
QKeyEvent::modifiers() 返回shift、ctrl、alt、meta和groupswitch虚拟键状态
QKeyEvent::nativeScanCode() 返回实际键码
QKeyEvent::nativeModifiers() 返回CapsLock、NumLock和ScrollLock实际键状态
QKeyEvent::isAutoRepeat() 判断长按
网络资源只作参考,多跟踪源码,以源码为主
4.参考文献
【1】https://blog.youkuaiyun.com/stpeace/article/details/51619704
【2】https://bbs.youkuaiyun.com/topics/360138798
【3】https://blog.youkuaiyun.com/robertkun/article/details/38081301