Qt/PyQt中使用系统全局的快捷键

除了全局快捷键部分外,其他的都比较简单,都是我实现“onekeycodehighlighter"中碰到的一些小问题,这里顺面整理一下。事实上,稍微懂一点的人,去看看one key code highlighter的源代码都能明白了。这里相当于将其详细的剖析一下。。。。。。。另外,实现上用Python+PyQt,事实上,主要的部分是对Qt的一些类的使用,所以其实看懂了C++的Qt中使用上是一样的。啥?你看不懂Python?好的,这就是我为什么靠C++吃饭,却学习JAVA,JavaScript,Lua,Python,Bash的一个原因,不然你看不懂别人在写啥-_-!(当然,我基本上也就学到能看懂)
对于pyQt完全不懂的,这里也不用看了,《pyqt的学习(1) 入门》,《pyqt(2) 对话框...

概述

使用系统全局的快捷键总是键很酷的事情,在你的程序已经失去焦点的时候,还能响应用户的按键,完成任务,多酷啊。特别的,我的one key code highlighter只有一个SystemTrayIcon(托盘图标)和一些菜单,不使用系统全局的快捷键而用菜单去实现命令的话,我还不如用快捷方式去使用chc2c呢(就如我以前做的那样)。所以,对于这个我自己需要而实现的软件,怎么说,也需要有这个功能,无奈的是,偏偏Qt中其实原生不支持此功能,那么,只好放弃移植性去使用win32 API了。

Qt中的实现

主要的API为:(来自MSDN)

BOOL RegisterHotKey(          HWND hWnd,
    int id,
    UINT fsModifiers,
    UINT vk
);

在Qt中实现并不算什么大问题,《Qt中使用全局热键》中有一些说明,此文说明了一件事情,技术文章的价值不以篇幅来衡量,而是以技术含量衡量,此文没有太多的文字,但是详细解释了所有过程。
主要步骤为用RegisterHotKey向系统注册全局的快捷键,然后重载QApplication的winEventFilter函数,并响应msg为WM_HOTKEY时的消息,整个过程类似于在Windows下的OnMessage进行消息响应,只是这次是在Qt中。原文给出的示例代码如下:(原文排版有点乱,但是不损其技术价值)

bool winEventFilter(MSG *msg, long *result)
{
    if(WM_HOTKEY==msg->message)
    {
        qDebug()<<"winmsg return true";
        emit hotKey(int(msg->wParam),LOWORD(msg->lParam),HIWORD(msg->lParam));
        return TRUE;
    }
    return FALSE;
}
这种实现很简单,我就不多说了,Qt嘛,毕竟还是C++,只不过这里放弃移植性调用Win32 API,并且响应消息而已,没有什么太多新的东西。

PyQt中的实现

相对于Qt中的实现来说,对于Qt中没有的东西,很显然PyQt中也很难有了,那么,我们还是只能通过调用Win32 API了,而在Python中调用Win32 API就没有那么太简单了。。。。。。。
介绍的是用ctypes来调用,当然,因为感觉此部分会与本主题太偏,所以额外写了一篇文章讲述。《Python与C之间的相互调用(Python C API及Python ctypes库)》,看了前文就会知道,其实用Python C API包装以下RegisterHotKey也可以实现一样的效果,知识用ctypes更简单一些。
这里就直接讲RegisterHotKey的调用了。以下是一些代码片段。。。。。

from ctypes import c_bool, c_int, WINFUNCTYPE, windll
from ctypes.wintypes import UINT

prototype = WINFUNCTYPE(c_bool, c_int, c_int, UINT, UINT)
paramflags = (1, 'hWnd', 0), (1,'id', 0), (1,'fsModifiers', 0), (1,'vk', 0)
self.RegisterHotKey = prototype(('RegisterHotKey', windll.user32), paramflags)

r = self.RegisterHotKey(c_int(self.mainWindow.winId()), HOT_KEY_ID, config.modifier, ord( config.hotkey.upper() ))
if not r:
      QtGui.QMessageBox.critical(None, 'Hot key','Can't Register Hotkey Win + Z')
      sys.exit(1)
这里用了比直接调用RegisterHotKey更复杂的方法来使用ctypes,(在《Python与C之间的相互调用(Python C API及Python ctypes库)》中描述了最简单的办法),好处是实现了“命名参数”及参数默认值,这里虽然实际没有使用-_-!另外,利用config中的配置的大写字母的ord,来表示Windows中的虚拟键值真是很方便,为什么这样能省去那一大堆的VK_*定义?因为WinUser.h中就是这样定义这些VK_*的。。。。。。。
还有,mainWindow实际是一个QMainWindow的对象,其winId函数可以获取到Windows窗口的句柄,这里将其转化为c_int而不是HWND,因为在Python中不允许从int到HWND的转换(这有点扭曲),知道原因的请告诉我。完成了这些后,QApplication的winEventFilter函数的重载还是少不了的。

以下是我的一段实现代码:

# these code don't have compatibility with other OS
    def winEventFilter(self, msg):
        debug_out("Message:" + str(hex(msg.message)) )
        if msg.message == WM_HOTKEY:
            if isClipboardEmpty():
                self.mainWindow.trayIcon.showMessage("failed","Clipboard is Empty.")
                return True, 0
            debug_out("Got the Hotkey!")
            debug_out(config.filename)
            
            import imp
            imp.reload(config)
            chc2c(self.mainWindow.syn, config.color, config.isLineNumber, config.filename)
            self.mainWindow.trayIcon.showMessage("success","transformed the data in clipboard to html.")
            return True, 0
        
        return False, 0

基本思路与C++中并无差异,查找到WM_HOTKEY,然后响应之。我这里利用了reload来达到每次都动态查询配置的效果^^chc2c就是我的主要函数。
以上就是PyQt中实现全局快捷键的全部过程了。

另外,我本来以为假如愿意使用PyWin32的话,直接可以调用其中的RegisterHotKey,后来竟然在里面没有找到,奇了怪了。

参考文章

Qt中使用全局热键

完整源代码获取说明

由于篇幅限制,本文一般仅贴出代码的主要关心的部分,代码带工程(或者makefile)完整版(如果有的话)都能用Mercurial在Google Code中下载。文章以博文发表的日期分目录存放,请直接使用Mercurial克隆下库:

https://onekeycodehighlighter.googlecode.com/hg/

Mercurial使用方法见《分布式的,新一代版本控制系统Mercurial的介绍及简要入门》

要是仅仅想浏览全部代码也可以直接到google code上去看,在下面的地址:

http://code.google.com/p/onekeycodehighlighter/source/browse/



Qt/PyQt中使用系统全局的快捷键相关推荐

  1. Qt开发中获取系统相关信息的方法,值得收藏参考

    本文转自https://zhuanlan.zhihu.com/p/111005951,这篇写的很详细,但是macos相关的只有一部分太少了,基本都是Windows的,我个人后续也会把相关的系统调用方式 ...

  2. 在PyQt中构建 Python 菜单栏、菜单和工具栏

    摘要:菜单.工具栏和状态栏是大多数GUI 应用程序的常见且重要的图形组件.您可以使用它们为您的用户提供一种快速访问应用程序选项和功能的方法. 本文分享自华为云社区<Python 和 PyQt:创 ...

  3. python qt库,用于 Python 的高级 GUI 库(Qt 和 PyQt)(1)Unix系统 -电脑资料

    Qt 工具箱是一个使用广泛的跨平台 GUI 工具箱,可用于 Windows .Linux.Mac OSX 和许多手持平台, Qt 工具箱是一个使用广泛的跨平台 GUI 工具箱,可用于Windows.L ...

  4. PyQt(Python+Qt)学习随笔:Qt Designer中部件的调色板palette属性和字体font属性设置

    一.调色板 在Qt Designer的部件属性中,有个部件调色板(palette)的属性,进入后,如下图所示: 1.调色板palette Qt中提供的调色板palette用于管理控件的外观显示,对应P ...

  5. 台式win7f1到f12热键取消_Windows 7旗舰版系统中键盘F1到F12快捷键的作用详解

    Windows 7旗舰版系统中键盘F1到F12快捷键的作用详解跟大家分享,在键盘上面大家都知道最上面有一排F1到F2的按键,这些是windows的功能键,可以提供我们一些通常的快捷操作,如果你掌握了这 ...

  6. PyQt(Python+Qt)学习随笔:Qt Designer中部件的accessibleDescription和accessibleName辅助阅读属性

    accessibleDescription和accessibleName属性都是用于残疾人辅助阅读的,这两个属性都有国际化属性(关于国际化请参考<PyQt(Python+Qt)学习随笔:Qt D ...

  7. 【Qt】在QtCreator中使用Ctrl+Shift+f快捷键打开高级查找窗口失效的解决方法

    1.问题描述 Win10操作系统环境下,在QtCreator中使用Ctrl+Shift+f快捷键打开高级查找窗口失效. 2.原因分析 Ctrl+Shift+f快捷键在各种输入法中,常用来做中文简体和繁 ...

  8. uchome中的$_SC:系统全局配置

    $_SC:系统全局配置 $_SBLOCK:未知 $_SCONFIG:站点配置信息(跟数据表uchome_config挂钩) $_SCOOKIE:Cookie信息 $_SGLOBAL:各类全局信息 $_ ...

  9. PyQt(Python+Qt)学习随笔:Qt Designer中部件的快捷菜单策略(contextMenuPolicy)取值及含义

    在Qt Designer中可以设置部件的快捷菜单策略,快捷菜单通过在部件上点击鼠标右键触发. 快捷菜单策略通过枚举类型Qt.ContextMenuPolicy来定义,对应枚举类型取值及含义如下: 通过 ...

最新文章

  1. AppBaseJs 类库 网上常用的javascript函数及其他js类库写的
  2. C#语言与面向对象技术(5)
  3. matlab基础入门之教你如何实现最小二乘法(附MATLAB代码)
  4. 电脑开机密码忘记了怎么办?
  5. bootstrap 树形表格渲染慢_layUI之树状表格异步加载组件treetableAsync.js(基于treetable.js)...
  6. java 预览office_java在线预览office
  7. 【转载】架构师速成-如何高效编程
  8. 【NOIP2001】【Luogu1029】最大公约数和最小公倍数问题(GCD,枚举)
  9. npm配置镜像、设置代理
  10. Web 开发的 JavaScript 框架资料收集(15款)
  11. 人脸识别数据集之MS-Celeb-1M
  12. 如何在计算机设置鼠标宏,鼠标宏怎么设置,教您鼠标如何设置宏
  13. 黑苹果alc269声卡仿冒id_笔记本制作仿冒声卡驱动AppleHDA最详细教程
  14. 第3期——WLAN标准协议
  15. PCIe的内存地址空间、I/O地址空间和配置地址空间
  16. python教程自带数据库_Python入门进阶教程-数据库操作
  17. 燕云台的滑铁卢——豆瓣的营销推广价值
  18. vc驿站视频教程笔记4 Cstring 讲解
  19. 那些年啊,那些事——一个程序员的奋斗史 ——53
  20. 2021.5.5笔记 多态

热门文章

  1. c语言太极图编程语言,利用C语言的Cairo图形库绘制太极图实例教程.pdf
  2. 理解和认识udev(转载)
  3. java web.xml 监听器_十:JavaWeb中的监听器(一)
  4. 2019考研调剂信息 计算机专业,东莞理工学院2019年考研调剂信息(计算机科学与技术、环境工程专业)...
  5. 量子计算机神器,量子计算技术再获神器 科学家开发出新的成像技术
  6. php 类示例,PHP类实例教程(二十二):类型提示
  7. java moment 日期转换_关于日期:如何使用Java 8 DateTime API转换修改后的儒略日数字...
  8. linux进程khungtaskd,Linux查看进程的所有信息的方法示例
  9. 混合办公时代来了?携程试点每周两天居家办公,76%的员工主动报名!
  10. 皮一皮:狭路相逢勇者胜...