pyqt的全局键盘热键

来源:互联网 发布:单片机论文 编辑:程序博客网 时间:2024/05/21 17:12

**

pyqt或qt默认不支持全局鼠标事件和全局键盘事件。以下将介绍全局键盘热键的写法:

**

全局键盘事件需要调用win32 api的功能。首先说明python自带的pywin32并不完整,所以我们要直接调用系统win32dll。但是我还是要说一下pywin32的安装。

1.网上的教程一般都用到了pyHook这个库。但是我用的python3,所以需要一些特别的步骤来弄出python3版的pyHook。

http://blog.csdn.net/bo_mask/article/details/76002273
这里是详细的搞法,值得注意的是我期间遇到的一些问题。
安装完运行库以后swig.exe还是无法编译,于是我又安装了vs2015构建工具。就可以了。
其实网上已经有人给出了编译好的版本,不过我没亲自试验过。嫌上面步骤比较麻烦的可以下载试试看。
http://download.csdn.net/download/shangkumi/10139865
只找到这个3.5版本的,但是我是3.6.。。所以嘛~~自力更生喽~

安装pywin32时需要下载与python对应的版本。不管你电脑是32位还是64位,pywin32的版本和位数以python的版本和位数为主。否则位数不对,以后会报错!!

http://www.cnblogs.com/min0208/archive/2012/05/24/2515584.html
这个是安装pywin32.exe时安装不上的原因。主要是python路径加入注册表就可以正常安装了。方法很好用。

这时,所有都已经安装好,发现效果并不是很好用,键盘事件和鼠标事件都有bug,我没能解决。

2.下定决心直接调用win32dll开搞。

开搞之前先理清几个问题。

win32的api一共三个dll。
http://blog.csdn.net/xdc_zy/article/details/76359094?locationNum=5&fps=1

这里我告诉你们一个很好的方法,下载一个dll查看器,可以很方便的查看各个dll里面的函数名。
因为你在调用时不清楚你想要的函数在哪个dll里面。

RegisterHotKey这个函数在windll.user32里面。
调用需要ctypes

from ctypes import  windll

然后这样直接调用。也可以按照如下方法调用。看自己喜好~~

windll.user32.RegisterHotKey()

http://blog.csdn.net/vagrxie/article/details/5252302
我仔细研究过这篇文章。。。没办法,人家水平太高,我就分享一下我的阅读经验吧。

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.winId()), 0x0000, 0, 4)if not r:    print("不知道啥原因,总之失败了~~")

上面是另一种调用方法,非常高端大气。下面我们来解析一下到底是啥意思。

前两行都是c的数据类型。这样写可以保证类型明确。
用到了ctypes的WINFUNCTYPE函数

from ctypes import WINFUNCTYPE, c_bool, c_intfrom ctypes.wintypes import UINT

http://blog.csdn.net/u010786109/article/details/41890131?locationNum=8&fps=1
这里是一些ctypes的介绍,不过我是没耐心看完了。你们加油~

paramflags里面是参数名。结合这个参考。
http://baike.sogou.com/v8031454.htm?fromTitle=RegisterHotKey

当然,这些都不是最主要的,只要你调用的时候参数类型搞对就行了,不用非得按照第二种方法来。其实直接windll.user32.RegisterHotKey()也挺好的。

准确的来说WINFUNCTYPE返回了函数指针。这样的话就有了第三行self.RegisterHotKey的调用。
它的第一个参数是个返回值,不填的话你可以试试嘛~~嘿嘿,你懂得。

**下面讲一讲这个函数的参数问题:
窗口句柄,系统可以根据这个句柄找到是哪个程序调用的这个函数。然后给它‘特殊’照顾
键码id,自己随便填,用来表示这个热键的名字。没啥用。
辅助键码,0是没有,其他的可以根据情况来弄,ctrl,alt,tab,都可以,不过要填虚拟键码。
热键键码,填啥就是啥,鼠标的不管用,键盘的管用。
http://baike.sogou.com/v374687.htm
关于键码对应的数字可以从这里面找。左边是十进制,右边是十六进制。推荐直接填十进制。好搞。**

上面只是调用了这个函数。意思就是告诉系统,我要注册热键。所以,按下热键时,系统会主动给程序发消息。但是这个消息要怎么接受呢?

上面大神用的winEventFilter这个事件,但是在qt5里面已经换成了nativeEvent事件,它位于Qwidget里面。大家可以通过文档查看。
http://doc.qt.io/qt-5/qwidget.html

from ctypes.wintypes import *def nativeEvent(self, eventType, message):    msg2 = ctypes.wintypes.MSG.from_address(message.__int__())#ctypes.wintypes    if msg2.message == 0x0312:        print("成功了吧~~")        return False,message

注意,事件返回值很重要。一般返回假,因为真时会阻塞,卡死。
msg2是把参数message进行转换,否则同样不行。
0x0312就是WM_HOTKEY拉,因为python不知道啥原因。那些东西都没有被定义,所以只能输入数字拉~~

完整代码朕就不贴了,反正也说的差不多了。如果有纰漏再补充吧。
还有就是特别感谢群主大大的帮助。群号246269919
如果有什么疑问可以进群艾特我,我叫柯哀

原创粉丝点击