Qt全局热键实现
监听系统原生事件
Qt作为跨平台的框架,实现的功能是在每个平台都共有的部分,而有的功能可能由于某些原因不能跨平台就没有,这时候就需要调用系统原生的API,比如全局热键的功能、电池休眠事件监听等。窗口的原生事件
窗口的原生事件可以通过重载QWidget::nativeEvent(constQByteArrayeventType,voidmessage,longresult)来实现。在函数中返回true会停止传递,如果返回false会继续由Qt处理事件。当窗口有句柄的时候,触发了平台原生的事件就会调用此函数。由eventType标识本机平台事件,这些事件的参数在message中传递。不同平台的eventType、message如下:
Platform
EventTypeIdentifier
MessageType
ResultType
Windows
windowsgenericMSG
MSG
LRESULT
macOS
NSEvent
NSEvent
XCB
xcbgenericeventt
xcbgenericeventt
下面举个例子,比如当前窗口在做一些操作,笔记本合上盖子进入休眠,要监听电池相关的事件:boolMainWidget::nativeEvent(constQByteArrayeventType,voidmessage,longresult){if(eventTypewindowsgenericMSGeventTypewindowsdispatcherMSG){MSGmsgstaticcastMSG(message);if(msgmessageWMPOWERBROADCAST){if(msgwParamPBTAPMSUSPEND){qDebug(系统休眠);}elseif(msgwParamPBTAPMRESUMESUSPENDmsgwParamPBTAPMRESUMEAUTOMATIC){qDebug(系统唤醒);}}}returnQWidget::nativeEvent(eventType,message,result);}应用级原生事件
像全局热键这样的事件是应用级别的,事件的监听就要放在app上。通过继承QAbstractNativeEventFilter来实现自己的原生事件过滤器并安装到app上即可。当有原生事件触发后就会调用事件过滤器的virtualboolnativeEventFilter(constQByteArrayeventType,voidmessage,long)函数。
【领QT开发教程学习资料,点击下方链接莬费领取,先码住不迷路】
点击领取Qt开发(视频教程文档代码项目实战)
要处理热键的话重写函数如下:boolMyWinEventFilter::nativeEventFilter(constQByteArrayeventType,voidmessage,long){if(eventTypewindowsgenericMSG){MSGmsgstaticcastMSG(message);if(msgmessageWMHOTKEY){判断是否为指定热键按下}}returnfalse;}热键的注册
上面处理好了事件发生后的步骤,还需要告诉系统哪些算是热键。注册用到的原生API有:BOOLRegisterHotKey(HWNDhWnd,响应该热键的窗口句柄,由于是应用级的,可以不传Intid,该热键的唯一标识UINTfsModifiers,该热键的辅助按键,Ctrl、Alt、ShiftUINTvk该热键的键值);BOOLUnregisterHotKey(HWNDhWnd,响应该热键的窗口句柄,同不传Intid该热键的唯一标识);
注册时按键的虚拟码可以去官网查询。
注册按键的函数一般都是字符串的形式,可以自己写个转换函数,也可以使用Qt的QKeySequence先得到热键的Qt的键盘码,再映射到windwos的虚拟码。具体实现
具体代码就不贴了,在Github上有个封装好各个平台的全局热键的仓库,QHotkey
windows相关实现在QHotkeyQHotkeyqhotkeywin。cpp中,里面就是调用RegisterHotKey来实现的。