全局热键
This commit is contained in:
parent
9f90499259
commit
9ccad8c431
19 changed files with 271 additions and 3 deletions
3
.gitignore
vendored
Normal file
3
.gitignore
vendored
Normal file
|
@ -0,0 +1,3 @@
|
|||
tmp
|
||||
tmp/*
|
||||
*.pyc
|
2
.project
2
.project
|
@ -1,6 +1,6 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<projectDescription>
|
||||
<name>PyQtGithub</name>
|
||||
<name>PyQt</name>
|
||||
<comment></comment>
|
||||
<projects>
|
||||
</projects>
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<?eclipse-pydev version="1.0"?><pydev_project>
|
||||
<pydev_property name="org.python.pydev.PYTHON_PROJECT_INTERPRETER">Python35</pydev_property>
|
||||
<pydev_property name="org.python.pydev.PYTHON_PROJECT_VERSION">python 3.0</pydev_property>
|
||||
<pydev_property name="org.python.pydev.PYTHON_PROJECT_INTERPRETER">Default</pydev_property>
|
||||
<pydev_pathproperty name="org.python.pydev.PROJECT_SOURCE_PATH">
|
||||
<path>/${PROJECT_DIR_NAME}</path>
|
||||
</pydev_pathproperty>
|
||||
|
|
|
@ -25,4 +25,6 @@
|
|||
|
||||
### 11.<a href="浏览器获取Cookie">浏览器获取Cookie</a><br />
|
||||
|
||||
### 12.<a href="截图画矩形">截图画矩形</a><br />
|
||||
### 12.<a href="截图画矩形">截图画矩形</a><br />
|
||||
|
||||
### 13.<a href="全局热键">全局热键</a><br />
|
110
全局热键/HotKey.py
Normal file
110
全局热键/HotKey.py
Normal file
|
@ -0,0 +1,110 @@
|
|||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
'''
|
||||
Created on 2017年12月11日
|
||||
@author: Irony."[讽刺]
|
||||
@site: http://alyl.vip, http://orzorz.vip, https://coding.net/u/892768447, https://github.com/892768447
|
||||
@email: 892768447@qq.com
|
||||
@file: HotKey
|
||||
@description:
|
||||
'''
|
||||
import ctypes # @UnusedImport
|
||||
import ctypes.wintypes
|
||||
from datetime import datetime
|
||||
import sys
|
||||
|
||||
from PyQt5.QtWidgets import QWidget, QApplication, QVBoxLayout,\
|
||||
QMessageBox, QTextBrowser, QPushButton
|
||||
|
||||
|
||||
# 参考
|
||||
# https://github.com/wujunwei/python-cookbook/blob/6e550d1a2b2b045cb07e56dd0198ccf01a2f3ea1/HotKey.py
|
||||
# https://github.com/chenyijie4238215/notebook/blob/ba11fcc43cf8d623d1d1a722c261ddc20ad6b941/global_hotkey/GlobalHotKey.py
|
||||
__Author__ = "By: Irony.\"[讽刺]\nQQ: 892768447\nEmail: 892768447@qq.com"
|
||||
__Copyright__ = "Copyright (c) 2017 Irony.\"[讽刺]"
|
||||
__Version__ = "Version 1.0"
|
||||
|
||||
WM_HOTKEY = 0x0312
|
||||
MOD_ALT = 0x0001
|
||||
MOD_NONE = 0x000
|
||||
MOD_CONTROL = 0x0002
|
||||
MOD_SHIFT = 0x0004
|
||||
MOD_WIN = 0x0008
|
||||
|
||||
Modifier = {
|
||||
"None": MOD_NONE,
|
||||
"Ctrl": MOD_CONTROL,
|
||||
"Alt": MOD_ALT,
|
||||
"Shift": MOD_SHIFT,
|
||||
"Win": MOD_WIN
|
||||
}
|
||||
|
||||
|
||||
class Window(QWidget):
|
||||
|
||||
KeyIds = {}
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(Window, self).__init__(*args, **kwargs)
|
||||
layout = QVBoxLayout(self)
|
||||
self.logView = QTextBrowser(self)
|
||||
self.logView.append("点击右上角关闭按钮会隐藏窗口,通过热键Alt+S来显示")
|
||||
self.logView.append("等待热键中")
|
||||
layout.addWidget(QPushButton("退出整个程序", self, clicked=self.onQuit))
|
||||
layout.addWidget(self.logView)
|
||||
|
||||
def unregisterHotKey(self, kid):
|
||||
ctypes.windll.user32.UnregisterHotKey(ctypes.c_int(self.winId()), kid)
|
||||
|
||||
def registerHotKey(self, kid, modifier, key):
|
||||
key = str(key).upper()
|
||||
_modifier = Modifier.get(modifier, None)
|
||||
if not _modifier:
|
||||
return QMessageBox.critical(self, "错误", "modifier key {0}未找到".format(modifier))
|
||||
success = ctypes.windll.user32.RegisterHotKey(
|
||||
ctypes.c_int(self.winId()), kid, _modifier, ord(key))
|
||||
if success:
|
||||
self.KeyIds[kid] = modifier + "+" + key
|
||||
self.logView.append("热键:{0}+{1}注册{2}".format(modifier, key, "成功"))
|
||||
else:
|
||||
self.logView.append("热键:{0}+{1}注册{2}".format(modifier, key, "失败"))
|
||||
|
||||
def onQuit(self):
|
||||
# 退出程序
|
||||
for kid in self.KeyIds:
|
||||
self.unregisterHotKey(kid)
|
||||
QApplication.instance().quit()
|
||||
|
||||
def closeEvent(self, event):
|
||||
# 忽略关闭窗口,直接隐藏
|
||||
self.hide()
|
||||
return event.ignore()
|
||||
|
||||
# 能监听热键,但是有个问题就是其它程序无法接受到事件
|
||||
# 比如Ctrl+S,在记事本里随便输入内容按下Ctrl+S发现无法保存
|
||||
def nativeEvent(self, eventType, message):
|
||||
if eventType == "windows_generic_MSG" or eventType == "windows_dispatcher_MSG":
|
||||
msg = ctypes.wintypes.MSG.from_address(message.__int__())
|
||||
# 这段代码无法运行
|
||||
# if ctypes.windll.user32.GetMessageA(ctypes.byref(msg), None, 0,
|
||||
# 0) != 0:
|
||||
if msg.message == WM_HOTKEY:
|
||||
if msg.wParam == 1: # Alt+S
|
||||
self.show()
|
||||
self.logView.append("id:{0}, {1} at time:{2}".format(
|
||||
msg.wParam, self.KeyIds.get(msg.wParam, None), datetime.now().strftime("%Y-%m-%d %H:%M:%S")))
|
||||
return True, 0
|
||||
return super(Window, self).nativeEvent(eventType, message)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
app = QApplication(sys.argv)
|
||||
w = Window()
|
||||
w.show()
|
||||
w.registerHotKey(1, "Alt", "S")
|
||||
w.registerHotKey(2, "Ctrl", "S")
|
||||
w.registerHotKey(3, "Shift", "S")
|
||||
w.registerHotKey(4, "Win", "S")
|
||||
w.registerHotKey(5, "Win", "Z")
|
||||
sys.exit(app.exec_())
|
9
全局热键/README.md
Normal file
9
全局热键/README.md
Normal file
|
@ -0,0 +1,9 @@
|
|||
# PyQt全局热键 For Windows Test
|
||||
|
||||
能监听热键,但是有个问题就是其它程序无法接受到事件<br/>
|
||||
比如Ctrl+S,在记事本里随便输入内容按下Ctrl+S发现无法保存<br/>
|
||||
|
||||
这里还有个比较好的例子<a href="https://github.com/yeejlan/py-stock-watcher/blob/87a7b7cfdeb01b44058fac6906c9cce5fd19cac0/modules/hotkey.py">hotkey.py</a>
|
||||
|
||||
# 截图
|
||||
<img src="ScreenShot/1.png" />
|
BIN
全局热键/ScreenShot/1.png
Normal file
BIN
全局热键/ScreenShot/1.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 12 KiB |
6
自动更新/README.md
Normal file
6
自动更新/README.md
Normal file
|
@ -0,0 +1,6 @@
|
|||
# 自动更新
|
||||
|
||||
1.dist/mylibs1.zip 为版本一的文件
|
||||
2.dist/mylibs2.zip 为版本二的文件
|
||||
|
||||
运行演示后,再次演示。需要把mylibs1.zip中的文件解压出来替换
|
BIN
自动更新/dist/mylibs
vendored
Normal file
BIN
自动更新/dist/mylibs
vendored
Normal file
Binary file not shown.
BIN
自动更新/dist/mylibs1.zip
vendored
Normal file
BIN
自动更新/dist/mylibs1.zip
vendored
Normal file
Binary file not shown.
BIN
自动更新/dist/mylibs2.zip
vendored
Normal file
BIN
自动更新/dist/mylibs2.zip
vendored
Normal file
Binary file not shown.
BIN
自动更新/dist/test.exe
vendored
Normal file
BIN
自动更新/dist/test.exe
vendored
Normal file
Binary file not shown.
0
自动更新/mylibs/__init__.py
Normal file
0
自动更新/mylibs/__init__.py
Normal file
23
自动更新/mylibs/testlibs.py
Normal file
23
自动更新/mylibs/testlibs.py
Normal file
|
@ -0,0 +1,23 @@
|
|||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
'''
|
||||
Created on 2017年5月7日
|
||||
@author: Irony."[讽刺]
|
||||
@site: alyl.vip, orzorz.vip, irony.coding.me , irony.iask.in , mzone.iask.in
|
||||
@email: 892768447@qq.com
|
||||
@file: 自动更新.mylibs.testlibs
|
||||
@description:
|
||||
'''
|
||||
|
||||
__Author__ = "By: Irony.\"[讽刺]\nQQ: 892768447\nEmail: 892768447@qq.com"
|
||||
__Copyright__ = "Copyright (c) 2017 Irony.\"[讽刺]"
|
||||
__Version__ = "Version 1.0"
|
||||
|
||||
|
||||
def version():
|
||||
return "0.0.1"
|
||||
|
||||
|
||||
def test():
|
||||
print("version: 0.0.1")
|
BIN
自动更新/pyos/mylibs/__init__.pyo
Normal file
BIN
自动更新/pyos/mylibs/__init__.pyo
Normal file
Binary file not shown.
BIN
自动更新/pyos/mylibs/testlibs.pyo
Normal file
BIN
自动更新/pyos/mylibs/testlibs.pyo
Normal file
Binary file not shown.
57
自动更新/setup.py
Normal file
57
自动更新/setup.py
Normal file
|
@ -0,0 +1,57 @@
|
|||
from distutils.core import setup
|
||||
import glob
|
||||
import os
|
||||
import py_compile
|
||||
import site
|
||||
import sys
|
||||
from zipfile import ZipFile, ZIP_DEFLATED
|
||||
|
||||
import py2exe # @UnusedImport
|
||||
|
||||
sys.argv.append("py2exe")
|
||||
|
||||
sitepackages = site.getsitepackages()[1]
|
||||
|
||||
py2exe_options = {
|
||||
"includes": [],
|
||||
"excludes": ["mylibs"], # 不打包这个
|
||||
"dll_excludes": ["MSVCP90.dll", "MSVCR90.dll"],
|
||||
"compressed": 1, # compressed 值为1,则压缩;为0,不压缩,默认为0
|
||||
"optimize": 2, # optimize - 合法值是字符串('','O','OO')或者整型数字 (0, 1, or 2)
|
||||
"bundle_files": 1
|
||||
}
|
||||
|
||||
setup(
|
||||
name="test",
|
||||
version="0.0.1",
|
||||
console=[
|
||||
{"script": "test.py"}
|
||||
], # 括号中更改为你要打包的代码文件名
|
||||
zipfile=None,
|
||||
options={'py2exe': py2exe_options},
|
||||
data_files=[
|
||||
# ("","./icon.ico"),
|
||||
]
|
||||
)
|
||||
|
||||
cores = glob.glob(os.path.join("mylibs", "*.py"))
|
||||
|
||||
for core in cores:
|
||||
py_compile.compile(
|
||||
core, cfile="pyos\\" + core + "o", doraise=True, optimize=2)
|
||||
print("compile core module ok")
|
||||
|
||||
# 添加到压缩文件
|
||||
zpfd = ZipFile("dist\\mylibs", "w", ZIP_DEFLATED)
|
||||
zpfd.write("mylibs")
|
||||
|
||||
for core in cores:
|
||||
zpfd.write("pyos\\" + core + "o", core + "o")
|
||||
zpfd.close()
|
||||
print("zip core file ok")
|
||||
|
||||
# D:\soft\Python34\python setup.py py2exe
|
||||
|
||||
# windows
|
||||
|
||||
# console
|
55
自动更新/test.py
Normal file
55
自动更新/test.py
Normal file
|
@ -0,0 +1,55 @@
|
|||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
'''
|
||||
Created on 2017年5月7日
|
||||
@author: Irony."[讽刺]
|
||||
@site: alyl.vip, orzorz.vip, irony.coding.me , irony.iask.in , mzone.iask.in
|
||||
@email: 892768447@qq.com
|
||||
@file: 自动更新.test
|
||||
@description:
|
||||
'''
|
||||
import sys
|
||||
sys.path.append("mylibs")
|
||||
import os
|
||||
from time import sleep
|
||||
from zipfile import ZipFile
|
||||
|
||||
|
||||
__Author__ = "By: Irony.\"[讽刺]\nQQ: 892768447\nEmail: 892768447@qq.com"
|
||||
__Copyright__ = "Copyright (c) 2017 Irony.\"[讽刺]"
|
||||
__Version__ = "Version 1.0"
|
||||
|
||||
|
||||
def update():
|
||||
# 更新
|
||||
from mylibs import testlibs # @UnresolvedImport
|
||||
v1 = testlibs.version() # 获取本地模块版本
|
||||
v2 = "0.0.2" # 模拟新版本(也可以从网络中检测)
|
||||
if v1 != v2: # 需要更新
|
||||
print("发现新版本:0.0.2")
|
||||
# 模拟从网络中下载更新包并解压(也可以包含图片等其它文件)
|
||||
with ZipFile("mylibs2.zip", "r") as zf:
|
||||
zf.extractall(os.path.dirname(sys.executable)) # 解压到当前目录
|
||||
return 1
|
||||
return 0
|
||||
|
||||
|
||||
def main():
|
||||
from mylibs import testlibs # @UnresolvedImport
|
||||
testlibs.test()
|
||||
print("当前版本:", testlibs.version())
|
||||
if update():
|
||||
print("更新完毕,即将重启")
|
||||
import platform
|
||||
if platform.system() == "Windows":
|
||||
import ctypes
|
||||
ctypes.windll.user32.MessageBoxW(
|
||||
0, "更新完毕,关闭对话框即将重启", "提示", 0x0000030)
|
||||
sleep(0.5)
|
||||
os.startfile(sys.executable) # 重启
|
||||
sys.exit() # 退出本身
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
input("press any key exit")
|
3
自动更新/编译.bat
Normal file
3
自动更新/编译.bat
Normal file
|
@ -0,0 +1,3 @@
|
|||
cd %~dp0
|
||||
py -3.4 setup.py py2exe
|
||||
pause
|
Loading…
Reference in a new issue