write by 九天雁翎(JTianLing) -- blog.csdn.net/vagrxie
讨论新闻组及文件
估计这种小的知识会有几篇文章,除了全局快捷键部分外,其他的都比较简单,都是我实现
“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,
intid,
UINT fsModifiers,
UINT vk
);
在Qt中实现并不算什么大问题,《
Qt中使用全局热键》中有一些说明,此文说明了一件事情,技术文章的价值不以篇幅来衡量,而是以技术含量衡量,此文没有太多的文字,但是详细解释了所有过程。
主要步骤为用RegisterHotKey向系统注册全局的快捷键,然后重载QApplication的winEventFilter函数,并响应msg为WM_HOTKEY时的消息,整个过程类似于在Windows下的OnMessage进行消息响应,只是这次是在Qt中。原文给出的示例代码如下:(原文排版有点乱,但是不损其技术价值)
boolwinEventFilter(MSG *msg, long*result)
{
if(WM_HOTKEY==msg->message)
{
qDebug()"winmsg return true";
emit hotKey(int(msg->wParam),LOWORD(msg->lParam),HIWORD(msg->lParam));
returnTRUE;
}
returnFALSE;
}
这种实现很简单,我就不多说了,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的调用了。以下是一些代码片段。。。。。
fromctypes importc_bool, c_int, WINFUNCTYPE, windll
fromctypes.wintypes importUINT
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() ))
ifnotr:
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 defwinEventFilter(self, msg):
debug_out(
"Message:
"+ str(hex(msg.message)) )
ifmsg.message == WM_HOTKEY:
ifisClipboardEmpty():
self.mainWindow.trayIcon.showMessage(
"failed
",
"Clipboard is Empty.
")
returnTrue, 0
debug_out(
"Got the Hotkey!
")
debug_out(config.filename)
importimp
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.
")
returnTrue, 0
returnFalse, 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/
原创文章作者保留版权 转载请注明原作者 并给出链接
write by 九天雁翎(JTianLing) -- blog.csdn.net/vagrxie
分享到:
相关推荐
Qt/PyQt无法连接数据库问题解决所需的两个dll文件
Qt Designer是PyQt程序UI界面的实现工具,Qt Designer工具使用简单,可以通过拖拽和点击完成复杂界面设计,并且设计完成的.ui程序可以转换成.py文件供python程序调用。本文主要通过用户登录需求描述Qt Designer工具...
PyQt快速开发与实战电子书并非源码。交流学习使用。资源来自于网络,如有侵权立即删除。
Opencv/PyQt-鼠标控制界面(二)
Opencv/PyQt——鼠标控制界面(一)
资源分类:Python库 所属语言:Python 资源全名:QT-PyQt-PySide-Custom-Widgets-0.1.8.tar.gz 资源来源:官方 安装方法:https://lanzao.blog.csdn.net/article/details/101784059
主要为大家详细介绍了pyqt5利用pyqtDesigner实现登录界面,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
主要介绍了PyQt中使用QtSql连接MySql数据库的方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
Qt全局热键Demo·
以上这篇在Qt5和PyQt5中设置支持高分辨率屏幕自适应的方法就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持软件开发网。 您可能感兴趣的文章:PyQt5 实现字体大小自适应分辨率的方法pyqt5...
http://www.riverbankcomputing.com/software/pyqt/intro 它由 Phil Thompson 创建。 PyQt 的实现被视作 Python 的一个模块。它由 300 多个类和接近 6000 个函数与方法构 成。作为一个跨平台的工具包, PyQt 可以在...
PyQt是Python语言和Qt库的成功融合。 偶然找到的这个版本, ubuntu16.04安装成功,对应Qt 5.9.0 sip 4.19.3 其他版本不保证
oracle-jmesdk-8-0-rr-nb-plugins.zip
pythonqt5教程从零开始_pyQt5QtDesigner简易⼊门教程 python3.6 & pyQt5 & QtDesigner 简易⼊门教程 1. python 官⽹下载安装python3.6并配置好环境; 2.cmd下 运⾏: pip install PyQt5 安装PyQt库; 3.cmd下运⾏: ...
适合初学者或多年开发者参考
pytest-qt, 用于 Qt ( PyQt4,PyQt5和 PySide ) 应用程序测试的pytest插件 pytest-qtpytest-qt是一个支持程序员为 PySide,PySide2和 PyQt的应用程序编写测试的 pytest插件插件。主要用途是使用 qtbot fixture,负责...
最近利用pyqt5写了一个小工具,想像微信一样可以在系统托盘驻留,并具备全局热键唤出、ESC键隐藏等功能,下面利用一个简单的UI界面来记录一下实现的过程 基本思路 利用QtDesigner制作UI界面; QSystemTrayIcon制作...
PyQt5系列教程(二)利用QtDesigner设计UI界面源码包,博文地址http://blog.csdn.net/djstavaV/article/details/50282527
本书共分四个部分:第一部分主要讲述Python基础知识,第二部分通过三个例子给出PyQt GUI应用程序的初步印象,第三部分深入讲述窗口部件布局、事件处理、窗口部件子类化、Qt图形架构和Qt的模型/视图等内容,第四部分...