QT全局热键(用nativeKeycode封装API,不跨平台)
在网上找了很长时间,大家都提到了一个QT全局热键库(qxtglobalshortcut),支持跨平台。在这篇文章中,我将只展示出windows平台下全局热键的设置。
这里提供的方法是在MyGlobalShortCut里面完成Windows的API封装,并在main.cpp中使用。
直接上代码:
MyWinEventFilter类:
class MyWinEventFilter :public QAbstractNativeEventFilter
{
public:
MyWinEventFilter(MyGlobalShortCut *shortcut);
~MyWinEventFilter();
virtual bool nativeEventFilter(const QByteArray &eventType, void *message, long*);
private:
MyGlobalShortCut *m_shortcut;
};
MyWinEventFilter::MyWinEventFilter(MyGlobalShortCut* shortcut) :m_shortcut(shortcut)
{}
MyWinEventFilter::~MyWinEventFilter()
{}
bool MyWinEventFilter::nativeEventFilter(const QByteArray &eventType, void message, long)
{
MSG *msg = static_cast(message);//static_cast<MSG*>(message)(把这段替换)
if (msg->message == WM_HOTKEY)
{
const quint32 keycode = HIWORD(msg->lParam);
const quint32 modifiers = LOWORD(msg->lParam);
bool res = m_shortcut->shortcuts.value(qMakePair(keycode, modifiers));
if (res)
{
m_shortcut->activateShortcut();
return true;
}
}
return false;
}
MyGlobalShortCut类:
class MyGlobalShortCut :public QObject
{
Q_OBJECT
public:
MyGlobalShortCut(QKeySequence key);
~MyGlobalShortCut();
void activateShortcut();
bool registerHotKey();
bool unregisterHotKey();
QHash<QPair<quint32, quint32>, MyGlobalShortCut*> shortcuts;
private:
QApplication *m_app;
MyWinEventFilter *m_filter;
QKeySequence m_key;
Qt::Key key;
Qt::KeyboardModifiers mods;
static quint32 nativeKeycode(Qt::Key keycode);
static quint32 nativeModifiers(Qt::KeyboardModifiers modifiers);
signals:
void activated();
};
MyGlobalShortCut::MyGlobalShortCut(QKeySequence key)
{
m_key = QKeySequence(key);
m_filter = new MyWinEventFilter(this);
m_app->installNativeEventFilter(m_filter);
registerHotKey();
}
MyGlobalShortCut::~MyGlobalShortCut()
{
unregisterHotKey();
}
void MyGlobalShortCut::activateShortcut()
{
emit activated();
}
bool MyGlobalShortCut::registerHotKey()
{
Qt::KeyboardModifiers allMods = Qt::ShiftModifier | Qt::ControlModifier | Qt::AltModifier | Qt::MetaModifier;
key = (m_key.isEmpty() ? Qt::Key(0) : Qt::Key((m_key[0] ^ allMods) & m_key[0]));
mods = m_key.isEmpty() ? Qt::KeyboardModifiers(0) : Qt::KeyboardModifiers(m_key[0] & allMods);
const quint32 nativeKey = nativeKeycode(key);
const quint32 nativeMods = nativeModifiers(mods);
shortcuts.insert(qMakePair(nativeKey, nativeMods), this);
return RegisterHotKey(0, nativeMods ^ nativeKey, nativeMods, nativeKey);
}
bool MyGlobalShortCut::unregisterHotKey()
{
return UnregisterHotKey(0, (quint32)nativeModifiers(mods) ^ (quint32)nativeKeycode(key));
}
quint32 MyGlobalShortCut::nativeKeycode(Qt::Key key)
{
switch (key)
{
case Qt::Key_Escape:
return VK_ESCAPE;
case Qt::Key_Tab:
case Qt::Key_Backtab:
return VK_TAB;
case Qt::Key_Backspace:
return VK_BACK;
case Qt::Key_Return:
case Qt::Key_Enter:
return VK_RETURN;
case Qt::Key_Insert:
return VK_INSERT;
case Qt::Key_Delete:
return VK_DELETE;
case Qt::Key_Pause:
return VK_PAUSE;
case Qt::Key_Print:
return VK_PRINT;
case Qt::Key_Clear:
return VK_CLEAR;
case Qt::Key_Home:
return VK_HOME;
case Qt::Key_End:
return VK_END;
case Qt::Key_Left:
return VK_LEFT;
case Qt::Key_Up:
return VK_UP;
case Qt::Key_Right:
return VK_RIGHT;
case Qt::Key_Down:
return VK_DOWN;
case Qt::Key_PageUp:
return VK_PRIOR;
case Qt::Key_PageDown:
return VK_NEXT;
case Qt::Key_F1:
return VK_F1;
case Qt::Key_F2:
return VK_F2;
case Qt::Key_F3:
return VK_F3;
case Qt::Key_F4:
return VK_F4;
case Qt::Key_F5:
return VK_F5;
case Qt::Key_F6:
return VK_F6;
case Qt::Key_F7:
return VK_F7;
case Qt::Key_F8:
return VK_F8;
case Qt::Key_F9:
return VK_F9;
case Qt::Key_F10:
return VK_F10;
case Qt::Key_F11:
return VK_F11;
case Qt::Key_F12:
return VK_F12;
case Qt::Key_F13:
return VK_F13;
case Qt::Key_F14:
return VK_F14;
case Qt::Key_F15:
return VK_F15;
case Qt::Key_F16:
return VK_F16;
case Qt::Key_F17:
return VK_F17;
case Qt::Key_F18:
return VK_F18;
case Qt::Key_F19:
return VK_F19;
case Qt::Key_F20:
return VK_F20;
case Qt::Key_F21:
return VK_F21;
case Qt::Key_F22:
return VK_F22;
case Qt::Key_F23:
return VK_F23;
case Qt::Key_F24:
return VK_F24;
case Qt::Key_Space:
return VK_SPACE;
case Qt::Key_Asterisk:
return VK_MULTIPLY;
case Qt::Key_Plus:
return VK_ADD;
case Qt::Key_Comma:
return VK_SEPARATOR;
case Qt::Key_Minus:
return VK_SUBTRACT;
case Qt::Key_Slash:
return VK_DIVIDE;
// numbers
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:
return key;
// letters
case Qt::Key_A:
case Qt::Key_B:
case Qt::Key_C:
case Qt::Key_D:
case Qt::Key_E:
case Qt::Key_F:
case Qt::Key_G:
case Qt::Key_H:
case Qt::Key_I:
case Qt::Key_J:
case Qt::Key_K:
case Qt::Key_L:
case Qt::Key_M:
case Qt::Key_N:
case Qt::Key_O:
case Qt::Key_P:
case Qt::Key_Q:
case Qt::Key_R:
case Qt::Key_S:
case Qt::Key_T:
case Qt::Key_U:
case Qt::Key_V:
case Qt::Key_W:
case Qt::Key_X:
case Qt::Key_Y:
case Qt::Key_Z:
return key;
default:
return 0;
}
}
quint32 MyGlobalShortCut::nativeModifiers(Qt::KeyboardModifiers modifiers)
{
// MOD_ALT, MOD_CONTROL, (MOD_KEYUP), MOD_SHIFT, MOD_WIN
quint32 native = 0;
if (modifiers & Qt::ShiftModifier)
native |= MOD_SHIFT;
if (modifiers & Qt::ControlModifier)
native |= MOD_CONTROL;
if (modifiers & Qt::AltModifier)
native |= MOD_ALT;
if (modifiers & Qt::MetaModifier)
native |= MOD_WIN;
return native;
}
//////////////////////////////////////////////////////////////////////////////////////////////
上面是类的封装,下面是使用:
在main()函数中加入:
QKeySequence keySequence=QKeySequence(tr(“ALT+A”));//设置快捷键ALT+A
MyGlobalShortCut *shortcut=new MyGlobalShortCut(keySequence);
connect(shortcut,SIGNAL(activated()),this,SLOT(onActivated()));
onActivated()
{
//全局热键被激活之后要做的事
}
这只是针对windows系统的实现,由于工作中现在只涉及windows,其他系统类似,主要就是实现nativeEventFilter()方法。
/////////////////////////////////////////////////////////////////////////////////////////////
(全文完)
http://blog.csdn.net/u011915578/article/details/46491055
QT全局热键(用nativeKeycode封装API,不跨平台)的更多相关文章
- Qt全局热键(windows篇)
Qt对于系统底层,一直没有很好的支持,例如串口并口通信,还有我们经常都会用到的全局热键,等等.既然Qt可能出于某种原因,不对这些进行支持,我们就只能自己写代码,调用系统相关的API了. 注意,这个 ...
- Qt全局热键(windows篇)(使用RegisterHotKey和句柄进行注册)
转载:http://www.cuteqt.com/blog/?p=2088 Qt对于系统底层,一直没有很好的支持,例如串口并口通信,还有我们经常都会用到的全局热键,等等.既然Qt可能出于某种原因,不对 ...
- Qt 5.x 全局热键 for windows
Qt 升级到5.x版本后,QAbstractEventDispatcher中函数发生变动,导致libqxt库中的qxtGlobalShortcut挂掉.参考qxtGlobalShortcut写了一个全 ...
- 使用WinAPI全局热键注册和全局模拟按键
一.全局热键注册 1.先引用DLL [System.Runtime.InteropServices.DllImport("user32.dll")] //导入WinAPI publ ...
- 第三方包jintellitype实现Java设置全局热键
Java原生API并不支持为应用程序设置全局热键.要实现全局热键,需要用JNI方式实现,这就涉及到编写C/C++代码,这对于大多数不熟悉C /C++的javaer来说,有点困难.不过幸好,国外有人已经 ...
- C# register global hotkey ,onekey 注册多个全局热键以及单个全局热键
我们需要用非Hook的方法,来给我们的app 或者winform注册热键. 就像下面的 , 欧陆词典注册的一个热键F6一样, 在winform最小化的情况下,也能够全局响应热键. 这里使用系统API来 ...
- Java设置全局热键——第三方包jintellitype实现
Java原生API并不支持为应用程序设置全局热键.要实现全局热键,需要用JNI方式实现,这就涉及到编写C/C++代码,这对于大多数不熟悉C/C++的javaer来说,有点困难.不过幸好,国外有人已经实 ...
- c#为程序添加全局热键的方法
在程序失去焦点或者在后台运行时,可以通过使用全局热键的方式,进行一些快捷的操作,如QQ默认操作中ctrl+alt+A调出截图功能. 在Windows中实现热键功能需要使用win32的Api函数Regi ...
- <转>MFC注册系统/全局热键。
<转>MFC注册系统/全局热键. 1. BEGIN_MESSAGE_MAP(CRS232TESTDlg, CDialog) //{{AFX_MSG_MAP(CRS232TESTDlg) O ...
随机推荐
- GCD的使用和面试题集锦
GCD 分为异步和同步 异步: dispatch_async ( 参数1 , { } 同步: dispatch_sync( 参数1 , { } 参数1 :队列 队列分为两种: dispatch_get ...
- KVC中setValuesForKeysWithDictionary:
本文转载于:http://my.oschina.net/u/2407613/blog/524879?p={{page}} 从字典映射到一个对象,这是KVC中的一个方法所提供的,这个方法就是 setVa ...
- iOS 16进制颜色转换10进制颜色
+(UIColor *)colorWithHexString:(NSString *)coloStr{ // 检索 去下空格和换行 转成大写 NSString *cString = [[col ...
- qt检测网络连接状态【只能检测和路由器的连接,不能测试到外网的连接】
#include <QCoreApplication>#include <QDebug>#include <QTextStream>#include <QDi ...
- 百度editor调用【图片上传阿里云】
百度editor调用简单,但是图片和文件上传阿里云就有点难度了.下面我详细说一下. 百度富文本编辑器下载地址:http://ueditor.baidu.com/website/download.htm ...
- System.Web.HttpException: 无法向会话状态服务器发出会话状态请求
System.Web.HttpException: 无法向会话状态服务器发出会话状态请求.请确保 ASP.NET State Service (ASP.NET 状态服务)已启动,并且客户端端口与服务器 ...
- codeforces 547B. Mike and Feet 单调栈
题目链接 用单调栈计算出一个数字, 左边第一个比他小的数字的位置, 右边比第一个他小的数字的位置, 然后len = r[i] - l[i] +1. ans[len] = max(ans[len], a ...
- win7中注册tomcat服务
非安装版tomcat下载后,在bin文件夹会有一个startup.bat文件,运行该文件即可启动tomcat了.不过在服务器配置tomcat的话,就通常需要注册为服务. 在/bin文件下还有tomca ...
- MYSQL 的数据读取方式
例子: create table T(X bit(8)); insert into T (X) values(b'11111111'); select X from T; 这个时候会发现这个X 是乱码 ...
- director.js教程
directive.js 初始化和注册路由 director.js 的主要对象是Router对象,构造方法如下: var router = new Router(routes); //routes为路 ...