python注册热键方式
#!/usr/bin/env python3
import win32con
import ctypes
import ctypes.wintypes
from threading import Thread,activeCount, enumerate
from time import sleep,time
class Hotkey(Thread):
user32 = ctypes.windll.user32
hkey_list = {}
hkey_flags = {} #按下
hkey_running = {} #启停
_reg_list = {} #待注册热键信息
def regiskey(self, hwnd=None, flagid=0, fnkey=win32con.MOD_ALT, vkey=win32con.VK_F9): # 注册热键,默认一个alt+F9
return self.user32.RegisterHotKey(hwnd, flagid, fnkey, vkey)
def get_reginfo(self):
return self._reg_list
def get_id(self,func):
self_id = None
for id in self.get_reginfo():
if self.get_reginfo()[id]["func"] == func:
self_id = id
break
if self_id:
self.hkey_running[self_id] = True
return self_id
def get_running_state(self,self_id):
if self.hkey_running.get(self_id):
return self.hkey_running[self_id]
else:
return False
def reg(self,key,func,args=None):
id = int(str(round(time()*10))[-6:])
fnkey = key[0]
vkey = key[1]
info = {
"fnkey":fnkey,
"vkey":vkey,
"func":func,
"args":args
}
self._reg_list[id] = info
# print(info) #这里待注册的信息
sleep(0.1)
return id
def fast_reg(self,id,key = (0,win32con.VK_HOME),func = lambda:print('热键注册开始')):
if not self.regiskey(None, id, key[0], key[1]):
print("热键注册失败")
return None
self.hkey_list[id] = func
self.hkey_flags[id] = False
return id
def callback(self):
def inner(self = self):
for flag in self.hkey_flags:
self.hkey_flags[flag] = False
while True:
for id, func in self.hkey_list.items():
if self.hkey_flags[id]:
args = self._reg_list[id]["args"]
if args:
# print(args) #这里打印传入给注册函数的参数
thread_it(func,*args)
else:
thread_it(func)
self.hkey_flags[id] = False
return inner
def run(self):
for id in self._reg_list:
reg_info = self._reg_list[id]
fnkey = reg_info["fnkey"]
vkey = reg_info["vkey"]
func = reg_info["func"]
self.fast_reg(id,(fnkey, vkey), func)
fn = self.callback()
thread_it(fn) # 启动监听热键按下线程
try:
msg = ctypes.wintypes.MSG()
while True:
if self.user32.GetMessageA(ctypes.byref(msg), None, 0, 0) != 0:
if msg.message == win32con.WM_HOTKEY:
if msg.wParam in self.hkey_list:
self.hkey_flags[msg.wParam] = True
self.user32.TranslateMessage(ctypes.byref(msg))
self.user32.DispatchMessageA(ctypes.byref(msg))
finally:
for id in self.hkey_list:
self.user32.UnregisterHotKey(None, id)
def thread_it(func, *args):
t = Thread(target=func, args=args)
t.setDaemon(True)
t.start()
def jump(func,hotkey):
self_id = hotkey.get_id(func)
while hotkey.get_running_state(self_id):
print(f"{self_id : } 你正在1秒1次的跳动")
sleep(1)
def stop_jump(start_id,hotkey):
hotkey.hkey_running[start_id] = False
print(f"{start_id} 即将停止")
sleep(1)
print(f'当前线程列表:{activeCount()}', enumerate())
def main():
hotkey = Hotkey()
start_id = hotkey.reg(key = (win32con.MOD_ALT,win32con.VK_HOME),func=jump,args=(jump,hotkey)) #alt home键 开始
hotkey.reg(key = (0,win32con.VK_END),func=stop_jump,args=(start_id,hotkey)) #alt end键 结束
hotkey.start() #启动热键主线程
print(f"当前总线程数量:{activeCount()}")
print('当前线程列表:', enumerate())
print('热键注册初始化完毕,尝试按组合键alt+Home 或者单键END看效果')
if __name__ == '__main__':
main()
以下是旧的代码,用起来比较麻烦。
#!/usr/bin/env python3
# _*_ coding: utf-8 _*_
# File : demo.py
# Author: DaShenHan&道长-----先苦后甜,任凭晚风拂柳颜------
# Date : 2019/6/28
import win32con
import ctypes
import ctypes.wintypes
from threading import Thread, Timer, activeCount, enumerate
from time import sleep
h_ids = [i for i in range(2)] # 创建两个热键序列
h_keys = {i: False for i in h_ids} # 初始化所有热键序列的标志符为False
h_dict = {} # 初始化一个空的字典,记录id与func
class Hotkey(Thread): # 创建一个Thread的扩展类
user32 = ctypes.windll.user32 # 加载user32.dll
# global h_ids, h_keys,h_dict
def regiskey(self, hwnd=None, flagid=0, fnkey=win32con.MOD_ALT, vkey=win32con.VK_F9): # 注册热键,默认一个alt+F9
return self.user32.RegisterHotKey(hwnd, flagid, fnkey, vkey)
def callback(self, id, func):
h_dict[id] = func # 这个id对应这个func,没有就是新增,有就是修改
def inner():
for key, value in h_dict.items():
print(f'总的热键池:{h_ids},当前热键序号:{key}, 当前热键功能:{value},当前热键状态:{h_keys[h_ids[key]]}')
while True:
for key, value in h_dict.items():
if h_keys[h_ids[key]]:
thread_it(value) # 另外开线程执行value
h_keys[h_ids[key]] = False
return inner
def run(self):
# print(self.user32)
if not self.regiskey(None,h_ids[0],win32con.MOD_ALT,win32con.VK_F9): # 注册快捷键alt+F9并判断是否成功,该热键用于执行一次需要执行的内容。
print(f"热键注册失败! id{h_ids[0]}") # 返回一个错误信息
if not self.regiskey(None,h_ids[1],0,win32con.VK_F10): # 注册快捷键F10并判断是否成功,该热键用于结束程序,且最好这么结束,否则影响下一次注册热键。
print(f"热键注册失败! id{h_ids[1]}")
# 以下为检测热键是否被按下,并在最后释放快捷键
try:
msg = ctypes.wintypes.MSG()
while True:
if self.user32.GetMessageA(ctypes.byref(msg), None, 0, 0) != 0:
if msg.message == win32con.WM_HOTKEY:
if msg.wParam in h_ids:
h_keys[msg.wParam] = True
self.user32.TranslateMessage(ctypes.byref(msg))
self.user32.DispatchMessageA(ctypes.byref(msg))
finally:
for i in h_ids:
self.user32.UnregisterHotKey(None, i)
# 必须得释放热键,否则下次就会注册失败,所以当程序异常退出,没有释放热键,
# 那么下次很可能就没办法注册成功了,这时可以换一个热键测试
def thread_it(func, *args):
t = Thread(target=func, args=args)
t.setDaemon(True)
t.start()
def settimeout(func, sec):
def inner():
func()
Timer(sec, inner).start()
thread_it(inner)
def setinterval(func, sec, tmrname, flag=True):
global timer_dict
timer_dict[tmrname] = flag
print("已设置tqtimer启用状态为:{}".format(flag))
def inner():
global timer_dict
if timer_dict[tmrname]:
func()
Timer(sec, inner).start()
thread_it(inner)
def clearinterval(timername):
global timer_dict
timer_dict[timername] = False
flag = timer_dict[timername]
print("已设置tqtimer启用状态为:{}".format(flag))
def test_start():
print("按下了开始键...the programe is running")
def test_stop():
print("按下了停止键...the programe is stopped")
def run_ok():
hotkey = Hotkey()
hotkey.start()
fn = hotkey.callback(0, test_start)
fn = hotkey.callback(1, test_stop)
thread_it(fn)
sleep(0.5)
count = activeCount()
print(f"当前总线程数量:{count}")
print('当前线程列表:', enumerate())
print('热键注册初始化完毕,尝试按组合键alt+F9 或者单键F10看效果')
while True:
pass
if __name__ == '__main__':
run_ok()
关于使用python3怎么注册一个全局热键就分享到这里了,希望以上内容可以对大家有一定的帮助,可以学到更多知识。如果觉得文章不错,可以把它分享出去让更多的人看到。
python注册热键方式的更多相关文章
- 不用注册热键方式在Delphi中实现定义快捷键(又简单又巧妙,但要当前窗体处在激活状态)
第一步:在要实现快捷键的窗体中更改属性“KeyPreview”为True:第二步:在要实现快捷键的窗体中的OnKeyPress事件中填入一个过程名称(在Object Inspector中),填写好后回 ...
- WPF注册热键后处理热键消息(非winform方式)
由于最近在做wpf版的截图软件,在处理全局热键的时候,发现国内博客使用的都是winform窗体的键盘处理方式,此方式需要使用winform的动态库,如此不协调的代码让我开始在github中寻找相关代码 ...
- RegisterHotKey注册热键,然后响应WM_HOTKEY消息
MSDN中的一个示例代码,步骤就是RegisterHotKey注册热键,然后响应WM_HOTKEY消息 @1:这个是系统热键 #include "stdafx.h" int _cd ...
- [修]python普通继承方式和super继承方式
[转]python普通继承方式和super继承方式 原文出自:http://www.360doc.com/content/13/0306/15/9934052_269664772.shtml 原文的错 ...
- 【转】python 退出程序的方式
[转]python 退出程序的方式 python程序退出方式[sys.exit() os._exit() os.kill() os.popen(...)] 知乎说明 http://www.zhihu. ...
- 理解 Python 的执行方式,与字节码 bytecode 玩耍 (上)
这里有个博客讲 Python 内部机制,已经有一些中文翻译. 可能因为我用的Python 3.5,例子跑起来有些不一样. 此外,我又查了其他一些参考资料,总结如下: Python 的执行方式 先看一个 ...
- 理解 Python 的执行方式,与字节码 bytecode 玩耍 (下)
上次写到,Python 的执行方式是把代码编译成bytecode(字节码)指令,然后由虚拟机来执行这些 bytecode 而 bytecode 长成这个样子: b'|\x00\x00d\x01\x0 ...
- [Spark][python]以DataFrame方式打开Json文件的例子
[Spark][python]以DataFrame方式打开Json文件的例子: [training@localhost ~]$ cat people.json{"name":&qu ...
- python 退出程序的方式
python程序退出方式[sys.exit() os._exit() os.kill() os.popen(...)] 知乎说明 http://www.zhihu.com/question/21187 ...
- delphi注册热键方法(一)
uses windows,menus; ..... //声明 HotKey_Key: Word; HotKey_Shift: Word; procedure WMHotKey(var msg : Tm ...
随机推荐
- snpEFF注释的vcf文件转化成maf文件
利用一个perl语言写的工具:snpeffTomaf 一行代码即可实现非常方便 github地址链接:https://github.com/tsy19900929/snpeffToMaf 将此仓库中的 ...
- tp 获取器的使用中应该怎么append 自定义数据
$data = model('organization_area')->getListByNoPage($where, 'create_time asc');foreach ($data as ...
- git的基础指令练习
#版本回退 git reset commitId --hard
- jsp第8个作业
public boolean addMail(Msg msg){ Statement st =null; Connection con=null; try{ //获取连接 con = getConne ...
- 原来sed不支持非贪婪匹配
场景 从GISAID上面批量下载下来的序列id很长,格式如下: 太长了,并且makeblastdb的时候-parse_seqids参数会导致报错,大概是长度太长不符合要求无法处理之类的. 不作处理去掉 ...
- geom_smooth trasparent alpha 透明度
stat_smooth (geom="line", alpha=0.3, size=3, span=0.5) + geom_line(stat="smooth" ...
- 使用npm包安装vant组件
- 使用EFCode First模式
1.添加EntityFrameworkCoreg和EntityFrameworkCore.Design这两个包 2.添加EF上下文类 例如下图如下: 1 using EntityModel; 2 us ...
- CH573 CH582 CH579蓝牙从机(peripheral)例程讲解二(广播内容修改)
在上一篇外设例程讲解中讲述了蓝牙从机的收发接口,这样可以快速的上手,那么接下来就讲解另一个重要设置,从机的广播. 在peripheral例程中,一直是以50ms的周期进行广播,使用手机软件扫描可以获取 ...
- c语言中%d %f %c %s等的区别
%d整型输出(%ld长整型输出)%f以小数形式输出,默认情况下保留小数点6位 这里是引用%f和%lf分别是float类型和double类型用于格式化输入输出时对应的格式符号.其中:float,单精度浮 ...