QT使用QHotKey实现全局热键时会发现,大键盘的小键盘的键位没有办法通过QT::Key()和QT::modifiers()直接处理,通过调试和查看QHotKey发现,在windows可以通过虚拟键码解决,在QHotKey的源码要加上以下处理;
QHotKey:
qhotkey_win.cpp:
quint32 QHotkeyPrivateWin::nativeKeycode(Qt::Key keycode, bool &ok)
{
ok = true;
switch (keycode)
{
case VK_NUMPAD0:
case VK_NUMPAD1:
case VK_NUMPAD2:
case VK_NUMPAD3:
case VK_NUMPAD4:
case VK_NUMPAD5:
case VK_NUMPAD6:
case VK_NUMPAD7:
case VK_NUMPAD8:
case VK_NUMPAD9:
case VK_MULTIPLY:
case VK_ADD:
case VK_SEPARATOR:
case VK_SUBTRACT:
case VK_DECIMAL:
case VK_DIVIDE:
return keycode;
default:
break;
}
if(keycode <= 0xFFFF) {//Try to obtain the key from it's "character"
const SHORT vKey = VkKeyScanW(static_cast<WCHAR>(keycode));
if(vKey > -1)
return LOBYTE(vKey);
}
...//其它源码不变
}
根据项目需求,这边创建热键是通过QLineEdit作为媒介,通过evnentFilter捕获键盘输入事件(即KeyPress):
bool eventFilter(QObject *watch, QEvent *event)
{
if(event->type()==QEvent::KeyPress){
QKeyEvent *keyEvent = static_cast<QKeyEvent*>(event);
qDebug()<<QKeySequence(keyEvent->key() | keyEvent->modifiers()).toString();
}
}
通过以上打印发现,小数字键盘的按键会被附上“Num”的字符串,根据这个点,当捕获到“Num”则进行一下处理:
QLineEdit *edit = new QLineEdit();
bool eventFilter(QObject *watch, QEvent *event)
{
if(event->type()==QEvent::KeyPress){
edit->setText(QKeySequence(keyEvent->key() | keyEvent->modifiers()).toString());
if(edit->text().contains("Num"){
int vk_num = keyEvent->key();
switch (keyEvent->key()) {
//小数字键盘的数字对应的QT键码
case Qt::Key_0:
case Qt::Key_1:
case Qt::Key_2:
case Qt::Key_3:
case Qt::Key_4:
case Qt::Key_5:
case Qt::Key_6:
case Qt::Key_7:
case Qt::Key_8:
case Qt::Key_9:
vk_num += 48;
break;
//小数字键盘的特除符号对应的QT键码
case 0x2a:
case 0x2b:
case 0x2c:
case 0x2d:
case 0x2e:
case 0x2f:
vk_num += 64;
break;
default:
break;
}
QHotKey *hotkey = new QHotKey(QKeySequence(vk_num),true,this);
}
}
}
通过以上方法获取到的就是windows的虚拟键码,然后通过虚拟键码传入QHotKey的构造函数即可兼容小键盘的全局热键;