QT全局键盘检测(即失焦后依旧可以检测到键盘事件)

大家搜到这个博客,肯定是业务或者学习中需要该功能。我是在设计一个项目中,涉及到按下T进行语音说话时设计到的。qt自带的QKeyEvent事件,并不是全局有效,只有在鼠标点击该窗口后才会产生对应的鼠标事件。对此我特地查了很多CSDN和公司的论坛,总结出网上主要有四种方法。

1、就是使用grabKeyBoard(),经过测试,并不能达到预期的效果。这个实际效果是在多个窗口一起存在时,其中一个窗口需要一直获取键盘事件:可以在这个窗口中捕获键盘事件,即grabKeyboard(); 这样这个窗口可以一直获取键盘事件。即使这个窗口不在激活状态下依然可以获取键盘事件。同时激活状态的窗口是获取不到任何键盘事件的,直到捕获了键盘事件的窗口释放键盘事件releaseKeyboard(),才能获取键盘事件。

2、使用钩子,涉及到各种WINAPI,网上也有现有的demo,事实上,那几个并不能编译通过,可能是我环境的问题,不太涉及,不做过多评论;

3、注册热键,现在我们新建一个类GlobalApplication,继承QApplication,并重载notify函数,经测试,编译通过,不过也不能达到预期的效果,因为这个只能识别按下,不能识别键盘释放,不符合需求。

4、使用第三方库QHotKey,这个B站有视频教学,详细指导了怎么下载和怎么使用。不过和方法三类似,无法符合需求。

就在大家束手无策的时候,突然找到一个API,是windows下的,用来监测键盘的状态码的。
主角开始上场:
究竟是什么能满足这样的需求,失焦后按下触发、抬起释放呢!
getKeyState();

函数原型:
SHORT GetKeyState( int nVirtKey );
函数只有一个参数,即虚拟键码。返回值为SHORT类型,即短整型。GetKeyState函数是用来获取指定的虚拟键码的按键的状态。得到的状态表示按键是按下了还是弹起的,还是状态切换(大小写状态、数字键盘锁状态)。

一、判断按键是否被按下。通过高位来进行判断,高位为1表示按键按下,高位为0表示按键弹起。具体方法如下:

 方法1:如果高位为1表示按键按下,此时返回值为负数(<0);如果高位为0表示按键弹起,此时返回值为正数(>0)。所以可以通过返回值与0比较进行判断按键是否按下。

 方法2:如果高位为1表示按键按下,此时返回值为1xxx xxxx xxxx xxxx,与0x8000(二进制 形式:1000 0000 0000 0000)进行按位与操作,结果为1;反之,如果按键弹起,按位与后结果为0。

 也可定义如下宏:#define  IsKeyPressed(nVirtKey)     ((GetKeyState(nVirtKey) & (1<<(sizeof(SHORT)*8-1))) != 0);

IsKeyPressed(nVirtKey)函数返回值为TRUE,则表示按键按下;反之表示按键弹起。

经测试:该函数使用qDebug()打印后,会出现4种状态值,按下是-127,-128,释放是0,1。
为什么会这样设计,个人觉得应该是为了记录上一次的按键状态,至于具体为什么这样用在哪里,本人水平有限,没有做过多研究,希望有人评论讲解。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值