之前用python3做游戏自动化脚本,用过很多东西,然后最终有一套完整的方案。在这里随便阐述一下核心思路:

游戏辅助的窗体设计方面:

不需要pyqt这种大型软件,写小工具用自带的tkinter就行了。当然,并不是自己纯手敲代码,是通过拖拽来实现的。怎么,你还不知道tkinter可以界面拖拽生成代码就行VB一样?

呵呵,PAGE了解一下。

游戏辅助的应用发布方面:

自然是用pyinstaller打包成32位版的exe发布了,带上程序图标,版本信息,都不是事儿

游戏核心模拟方面:

当然不是通过手敲代码实现了,而是通过调用目前市场上强大的dll插件了。比如com组件如大漠插件、乐玩插件。或者说,把易语言的一些模块编译成windll来调用也行哦

辅助窗体热键注册方面:

这些需要用到底层的东西了,用win32的东西实现的,可以实现注册全局热键。原理是单独一个线程用于检测热键按下,然后热键按下后单独开辟线程执行需要的功能。鉴于原生的太难写,我自己封装了并且写了一个demo。注册全局组合键和单独的热键都是没问题的。

前面三个方面仁者见仁了。后面这个我就贴个核心源码吧,免得以后找不到了。

下面贴一段新的代码:

#!/usr/bin/env python3

# -*- coding: utf-8 -*-

# File : 简单热键.py

# Author: DaShenHan&道长-----先苦后甜,任凭晚风拂柳颜------

# Date : 2020/3/4

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()

这里是没弄界面的源码,所以我就把主线程死循环阻塞了。运行后按alt+F9会打印按下了开始键,按F10会打印按下了停止键。

如果你在tkinter里面跑,直接把run_ok函数后面的while True:pass删掉,然后在init函数里面加入run_ok()就行了。这里指的用PAGE设计的tkinter程序哈!

那么窗体创建完毕就会自动阻塞主线程,其他监控热键的线程随主线程结束。启动期间独立运行互不干扰。

到此这篇关于python3注册全局热键的实现的文章就介绍到这了,更多相关python3 注册全局热键内容请搜索以前的文章或继续浏览下面的相关文章希望大家以后多多支持!

python3 全局热键_python3注册全局热键的实现相关推荐

  1. python3注册全局热键

    之前用python3做游戏自动化脚本,用过很多东西,然后最终有一套完整的方案.在这里随便阐述一下核心思路: 游戏辅助的窗体设计方面: 不需要pyqt这种大型软件,写小工具用自带的tkinter就行了. ...

  2. 拍牌神器是怎样炼成的(三)---注册全局热键

    要想在上海拍牌的超低中标率中把握机会.占得先机,您不仅需要事先准备好最优的竞拍策略,还要制定若干套应急预案,应对不时之需.既定策略交给计算机自动执行,没有问题.可是谁来召唤应急预案呢?使用全局热键应该 ...

  3. 对VB注册全局热键的思考——是不是RegisterHotKey的1个ID可以注册多组热键?

    最近在网络上看到用VB注册热键的代码,试了下,觉得很好用.经过一番分析,我又简化了一下源代码,把没有必要的代码删去,还是能成功.由此引发了一些思考,是不是RegisterHotKeyr的1个ID可以注 ...

  4. 使用uniapp注册全局组件

    首先我们要在全局  注册全局组件 创建一个组件后 在main.js文件下 当然注册组件首先要新建一个组件目录然后引入. //注册全局组件 //首先在文件下创建一个组件 import global fr ...

  5. vue注册全局方法:生成单号------年月日(4+2+2)+随机数n位 (前端生成单号,从接口取单号)

    vue注册全局方法:生成单号------年月日(4+2+2)+随机数n位 1.写方法 2.全局注册 3.页面中使用此方法 1.写方法 因为再vue中多次用到此方法,故而创建一个公用的文件内含多次被调用 ...

  6. python注册热键_RegisterHotKey注册快捷键

    因为我们还要在程序退出的时候,消除这个热键,   所以需要声明一个全局变量: HotKeyId:   Integer; 第一步: 在窗口的create事件中,加入以下代码 HotKeyId   := ...

  7. uni-app注册全局组件 - 符合easycom

    通知 本文已过时,HBuilderX已发布新的自定义组件方法:uni_modules 本文的/components/xx/xx.vue会在新版uni-app中与原生ui组件冲突. 新方法详见: [we ...

  8. 微信小程序----全局状态管理 (便于全局埋点等操作)

    说明 由于我是一个有着一颗玻璃心的博主,导致在2018年后博客很少更新.原因是由于我的分享并没有解决到部分人的问题,而导致被骂了.当时这颗玻璃心就碎了,所以这两年以来很是消极,博客很少更新.这里给那些 ...

  9. 不能返回函数内部new分配的内存的引用_JNI开发之局部引用、全局引用和弱全局引用(三)...

    阿里P7移动互联网架构师进阶视频(每日更新中)免费学习请点击:https://space.bilibili.com/474380680 这篇文章比较偏理论,详细介绍了在编写本地代码时三种引用的使用场景 ...

最新文章

  1. Andriod anim translate中的属性介绍
  2. 机械制造技术学习笔记(七)
  3. Struts1和Struts2的区别和对比(完整版)
  4. SUID SGID LINUX 权限安全设置
  5. Sql Server2005性能
  6. 802.11ac标准简介
  7. 什么能在main()函数之前或之后执行
  8. css 大于号 标签_web前端教程之怎样学好css?
  9. 一个传统媒体人转型创业的真实故事
  10. IDC发布2017年中国智慧城市IT十大预测
  11. HTML5 原生混合模式,html5 – Chrome中的Chrome css3混合混合模式错误
  12. java世博会_世博会申请由xcode修改
  13. Android常用应用市场包名
  14. html调用js的方法
  15. 中国管理信息化杂志中国管理信息化杂志社中国管理信息化编辑部2022年第16期目录
  16. ������ʾ����
  17. EPICS -- autosave模块使用示例
  18. Java发送http的get、post、put请求
  19. APC型光纤活动连接器有何特点?适合使用在什么场景?
  20. 【STC单片机学习】第五课:动手写代码之前必须的准备工作

热门文章

  1. Android浮窗权限判断
  2. Web前端—01HTML超文本标记语言
  3. 洛谷 3373 线段树
  4. 神雕侠侣手游服务器维护,《神雕侠侣》3月30日更新维护新服开启公告
  5. 前端常用事件案例——抽名字(抽奖)/搜索下拉菜单/微博文本框
  6. 鹏博士总经理陆榴遭免职 董事称事发突然
  7. MacBook Air 2014 安装NVME硬盘并纯UEFI安装和引导Win7
  8. python显示图片image_用Python语言显示图片的倒影效果
  9. 前端页面导出为xls、xlsx格式的excel文件
  10. 30款Linux 高性能网络开发库开源软件