Qt获取键盘按键事件(Windows API)----StateReader系列
2015-03-17 13:39
2679 查看
Qt对于系统底层,一直没有很好的支持,例如串口并口通信,还有我们经常都会用到的全局热键,等等。既然Qt可能出于某种原因,不对这些进行支持,我们就只能自己写代码,调用系统相关的API了。
需求:获取Caps Lock键的状态,并使程序在后台运行时能够及时得到Caps Lock键的状态。
方法有两种,一是注册全局热键(想法很好,可惜注册后这个键原先的功能就没了,不采用)。二是隔一段时间读取一次按键状态(很好用,而且CPU消耗也不大)
1. 使用RegisterHotKey函数 注册全局热键
BOOL RegisterHotKey( HWND hWnd, int id, UINT fsModifiers, UINT vk );
HWND类型是Windows中的窗口句柄类型,在Qt中,QWidget及其子类均可使用winId()函数得到。
在本文,第二个参数是”virtual key 虚拟键”相对应的数字。
后面两个参数,一个是修饰键,一个是普通按键。例如,假设我们想注册Ctrl+F4这个热键组合,则fsModifiers就是MOD_CONTROL,而vk就是VK_F4。
主要步骤为用RegisterHotKey向系统注册全局的快捷键,然后重载QApplication的winEventFilter函数,并响应msg为WM_HOTKEY时的消息,整个过程类似于在Windows下的OnMessage进行消息响应,只是这次是在Qt中。
2.GetKeyState() 定时读取状态
函数原型 SHORT GetKeyState(int nVirtKey);
其中,形参是虚拟键;
GetKeyState可以返回不同的值来表示键是否被按下、键是否被触发,或者是关闭状态。
进入正题部分:
这里我们继续用Thread来读取按键状态:
基本思路是每隔1s读取一次键盘状态,通过发送信号,来使另一个类中的槽来读取键盘的状态。
需求:获取Caps Lock键的状态,并使程序在后台运行时能够及时得到Caps Lock键的状态。
方法有两种,一是注册全局热键(想法很好,可惜注册后这个键原先的功能就没了,不采用)。二是隔一段时间读取一次按键状态(很好用,而且CPU消耗也不大)
1. 使用RegisterHotKey函数 注册全局热键
BOOL RegisterHotKey( HWND hWnd, int id, UINT fsModifiers, UINT vk );
HWND类型是Windows中的窗口句柄类型,在Qt中,QWidget及其子类均可使用winId()函数得到。
在本文,第二个参数是”virtual key 虚拟键”相对应的数字。
后面两个参数,一个是修饰键,一个是普通按键。例如,假设我们想注册Ctrl+F4这个热键组合,则fsModifiers就是MOD_CONTROL,而vk就是VK_F4。
主要步骤为用RegisterHotKey向系统注册全局的快捷键,然后重载QApplication的winEventFilter函数,并响应msg为WM_HOTKEY时的消息,整个过程类似于在Windows下的OnMessage进行消息响应,只是这次是在Qt中。
//MyApp类 class MyAPP : public QApplication{ ....... virtual bool winEventFilter(MSG *msg, long *result); signals: void getF10HotKey(); void getF11HotKey(); }; bool MyApp::winEventFilter(MSG *msg, long *result){ if(WM_HOTKEY == msg->message){ if(msg->wParam == VK_F10){ //qDebug("VK_F10 winEventFilter."); emit getF10HotKey(); } if(msg->wParam == VK_F11){ //qDebug("VK_F11 winEventFilter."); emit getF11HotKey(); } return true; } return false; } //QtTopic类 class QtTopic : public QWidget{ public: void registerGlobalKey(); private slots: void hotKeyF10Received(); void hotKeyF11Received(); }; void QtTopic::registerGlobalKey(){ //注册全局键 if(RegisterHotKey(this->winId(), 0x79, 0, VK_F10)){//0x79 is VK_F10, wParam is 121 qDebug("F10 registered for QtTopic."); } if(RegisterHotKey(this->winId(), 0x7A, 0, VK_F11)){//wParam is 122 qDebug("F11 registered for QtTopic."); } } void QtTopic::hotKeyF10Received(){ //F10被按下 qDebug("F10 received."); if(box->isChecked()) box->setChecked(false); void QtTopic::hotKeyF11Received(){ qDebug("F11 received."); if(!box->isChecked()) box->setChecked(true); } //Main int main(int argc, char *argv[]){ Q_INIT_RESOURCE(qttopic); MyApp app(argc, argv); QtTopic topic; topic.show(); QObject::connect(&app, SIGNAL(getF10HotKey()), &topic, SLOT(hotKeyF10Received())); QObject::connect(&app, SIGNAL(getF11HotKey()), &topic, SLOT(hotKeyF11Received())); return app.exec(); }
2.GetKeyState() 定时读取状态
函数原型 SHORT GetKeyState(int nVirtKey);
其中,形参是虚拟键;
GetKeyState可以返回不同的值来表示键是否被按下、键是否被触发,或者是关闭状态。
进入正题部分:
这里我们继续用Thread来读取按键状态:
基本思路是每隔1s读取一次键盘状态,通过发送信号,来使另一个类中的槽来读取键盘的状态。
#include "windows.h" //需要加入的头文件
//QueryKeyThread class QueryKeyThread : public QThread { Q_OBJECT ... public: void run(); signals: void QueryResult(bool cap, bool num); }; void QueryKeyThread::run() { while(!stopped) { bool caps = false, nums = false; if(GetKeyState(VK_CAPITAL) & 0x0001) { caps = true; } if(LOBYTE(GetKeyState(VK_NUMLOCK))) { nums = true; } emit QueryResult(caps, nums); msleep(1000); } }
//StateReader class StateReader : public QDialog { ... protected slots: //Thread Back void QueryResult(bool cap, bool num); ... }; StateReader::StateReader(QWidget *parent) : QDialog(parent), ui(new Ui::StateReader) { ... QueryKeyThread *pThread_KeyPress = new QueryKeyThread(); connect(pThread_KeyPress, SIGNAL(QueryResult(bool,bool)), this, SLOT(QueryResult(bool,bool))); pThread_KeyPress->start(); ... } void StateReader::QueryResult(bool cap, bool num) { if(cap) { qDebug() << "Caps ON"; systemIcon->setIcon(QIcon(":/images/up3.ico")); systemIcon->setToolTip("Caps On"); ui->checkBoxCap->setChecked(true); ui->checkBoxCap->setDisabled(true); } else { qDebug() << "Caps OFF"; systemIcon->setIcon(QIcon(":/images/down3.ico")); systemIcon->setToolTip("Caps OFF"); ui->checkBoxCap->setChecked(false); ui->checkBoxCap->setDisabled(true); } if(num) { ui->checkBoxNum->setChecked(true); ui->checkBoxNum->setDisabled(true); } else { ui->checkBoxNum->setChecked(false); ui->checkBoxNum->setDisabled(true); } }
相关文章推荐
- QT:如何获取鼠标坐标点和键盘响应事件
- QT事件处理,鼠标事件,按键键盘事件,定时器,进度条。
- Qt使用Windows Api模拟键盘事件,附Qt::key转windows键值
- js获取键盘按键响应事件(兼容各浏览器)
- JavaScript 获取键盘事件(键盘某个按键被按下)
- 如何用JS获取键盘上任意按键的值?兼容FireFox和IE js获取键盘ASCII码?js键盘事件全面控制
- js获取键盘按键响应事件(兼容各浏览器)
- [Windows API 函数] WinAPI: GetKeyNameText - 根据键盘消息获取按键名称
- qt 键盘按键事件 范例 keyPreEvent()
- Qt事件获取键盘响应(Ctrl,shift)
- JS 获取和响应键盘按键事件
- QT中文输入法状态下获取键盘输入事件
- 如何用JS获取键盘上任意按键的值?兼容FireFox和IE js获取键盘ASCII码?js键盘事件全面控制
- Qt 处理键盘按键事件:只能输入字母 keyPressEvent
- [Flex]Flex编程注意之自动获取焦点、监听全局键盘事件
- Flex编程注意之自动获取焦点、监听全局键盘事件
- 获取键盘键的值 集合 方便监控键盘事件
- 如何在程序中模拟键盘的按键事件?
- WinAPI: GetKeyNameText - 根据键盘消息获取按键名称
- GetKeyNameText - 根据键盘消息获取按键名称