Qml中的那些坑(三)---KeyEvent 的 key / virtualKey / scanCode

【写在前面】

        在 Qt 中,对于一个键盘事件 QKeyEvent ,通常包含三种键值:

        1、key:Qt 键值,例如 Qt::Key_Escape

        2、nativeVirtualKey:本机虚拟键值,例如 VK_ESCAPE ( windows )。

        3、nativeScanCode:本机扫描码。 


 【正文开始】

        在 Qml 中,也存在着键盘事件:KeyEvent

        看起来它与 QKeyEvent 没有什么太大的区别,然而实际上,它缺少 nativeVirtualKey

        当然,很多时候我们仅仅使用它的 key 足矣,但是一个坑是 Qt 键值并没有包含所有的按键。

        来看下面代码:

void MyWindow::keyPressEvent(QKeyEvent *ev)
{
    qDebug().noquote() << "按键:" << ev->text() << hex
                       << "key:" << ev->key()
                       << "nativeScanCode:" << ev->nativeScanCode()
                       << "nativeVirtualKey:" << ev->nativeVirtualKey();
}

        输出如下: 

        两个都是按键1,但第一个是数字键1,第二个却是小键盘的数字键1。 

        而它们的区别有两个,nativeScanCode nativeVirtualKey

        事实上,当一个按键按下的时候,会发生以下转换:

        前面提到了Qt 键值并没有包含所有的按键,因此可以想到,在 virtualKey 转换的时候,两个不同的按键1都被转换( 映射 )成了Qt::Key_1

        当然,如果仅仅是这样就算了,我们完全可以使用 nativeVirtualKey 来区分( 在C++中 ),然鹅在 Qml 中,恰好就没有nativeVirtualKey,这™就很尴尬了好吗。

        由于某些应用的特殊性( 例如:远程控制 ),因此我必须知道,到底是哪个按键按下了。

        能想到的解决方法有两个:

        1、不使用 Qml 的 KeyEvent,而是使用 keyPressEvent(QKeyEvent *event) 提供的 QKeyEvent::nativeVirtual 来区分。

        2、使用 Qml 的 KeyEvent,但需要进行额外的判断,对于这种方法,由于所有的按键都有其 scanCode,所以我们最后还是可以通过 scanCode 来区分不同的按键。


【结语】

        最后讲一下题外话。

        因为我做的是远程控制,所以仅仅是区分不同的按键远远不够。

        例如 Windows API 的 SendInput keybd_event( 被 SendInput 取代) 模拟按键事件时,就需要 virtualKey 值,也就是说最终还是得把 Qt Key 转换成 virtualKey

        所以在使用第二种方法的时候,仍然要进行转换,这里给一个KDE的工具(但是不完整而且仍不能区分所有键,所以我自己用的改进了一下):https://api.kde.org/frameworks/kwindowsystem/html/kkeyserver_8cpp_source.htmlicon-default.png?t=N7T8https://api.kde.org/frameworks/kwindowsystem/html/kkeyserver_8cpp_source.html

  • 4
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

梦起丶

您的鼓励和支持是我创作最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值