玩亚索很费q键和r键,所以想做一个键盘连点器。

功能要求

1.按下按键,开始连击,松开按键,连击停止;
2.只对q键和r键有效;
3.具备一定的稳定性,且按键松开后能够立即停止连击,不能拖泥带水;

依赖的库

1.键盘监听库:pynput(pyhook也可以监听键盘,但是安装麻烦)
2.模拟键盘输入的库:pywin32(pynput也可以模拟键盘输入,但是不够底层,不能用于游戏)
3.ctypes,用于获取模拟键盘事件时需要的扫描码参数
关于pywin32和ctypes进行键盘操作的一些用法可以在 这篇公众号文章.看到,在此感谢 孤独的S 这位老铁。

代码实现

  • 连点器需要两个函数来实现,一个是控制函数,一个是连点函数,两者并行,所以需要用到多线程
  • 控制函数和连点函数之间需要进行信息沟通,一开始的方案是利用全局变量,参考的是 这篇文章.
    一、利用全局参数的方式实现
from pynput.keyboard import Key, Listener
import time
import win32api
import win32con
import ctypes
import os
import threading#定义全局变量q作为连点的开关参数
q = 0# 监听按下
def on_pressq(key):global q#判断按下的键是不是q键if str(key)=="'"+'q'+"'" and q == 0:#如果是q键被按下,将全局变量q设为1q=1print('监听到按下q')#监听释放
def on_releaseq(key):global qif str(key)=="'"+'q'+"'":#如果q键被释放,全局变量q设为0q=0print('监听到释放q')
#定义连击函数
def press_q():global q#这个连点函数是要一直循环运行的while True:#如果全局变量q为1,那么开始连点if q == 1:#定义好获取相应按键的扫描参数的函数 MapVirtualKey = ctypes.windll.user32.MapVirtualKeyA   #连击5次q键,0x51是q键的虚拟码,后面的MapVirtualKey(0x51, 0)可以得到q键的扫描码#如果想在游戏中起作用,必须同时输入虚拟码和扫描码for i in range(5):win32api.keybd_event(0x51, MapVirtualKey(0x51, 0), 0, 0)time.sleep(0.01)win32api.keybd_event(0x51, MapVirtualKey(0x51, 0), win32con.KEYEVENTF_KEYUP, 0)print('自动按q')# 运行线程
#pynput源码中解释说Listener是一个继承自threading.Thread的类,所以在定义线程的时候采用这种语法
t1 = Listener(on_press=on_pressq, on_release=on_releaseq)
t2 = threading.Thread(target=press_q, name='sendThreadq')
t1.start()
t2.start()os.system("pause")

这个方法确实能用,然而存在一些问题,例如在连点过程中,监控q键按下与抬起的线程t1也一直在运行,这就导致全局变量q被频繁的反复赋值为1和0,q被赋值又会反过来影响连点线程,且多线程的执行顺序是不确定的,这就导致q键连点的次数与频率的不确定性:


对这个代码的两次实验,都是只按了一下q键,然而分别进行了11次和16次连点,连点速度不够稳定,且在输出栏的监测数据中可以看出,在连点的过程中q键的动作不断的被t1线程监测到,这也意味着全局变量q不断地被重新赋值,这加剧了代码的不稳定性,有时会出现松开q键,代码继续自动连点了十多次的情况。
二、使用信号量进行线程同步
这里参考了这篇文章. 利用信号量来稳定连点的次数,并辅以全局变量来控制监控线程的介入,避免两个进程之间的交叉影响。

from pynput.keyboard import Key, Listener
import time
import win32api
import win32con
import ctypes
import os
import threading#分别定义q和r键的信号量对象
semaphoreq = threading.Semaphore(0)
semaphorer = threading.Semaphore(0)#定义全局变量作为监测线程介入的开关
q = 0
r = 4def on_pressq(key):# 监听按键qglobal qif str(key)=="'"+'q'+"'" and q == 0:print('按下q',q)#q信号量加一semaphoreq.release()def on_pressr(key):# 监听按键rglobal rif str(key)=="'"+'r'+"'" and r == 4:print('按下r',r)#r信号量加一semaphorer.release()def press_q():global qwhile True:#消费一个q信号量semaphoreq.acquire()#全局变量q赋值为1,阻断监控函数的介入q = 1MapVirtualKey = ctypes.windll.user32.MapVirtualKeyA#time.sleep(0.1)for i in range(5):win32api.keybd_event(0x51, MapVirtualKey(0x51, 0), 0, 0)time.sleep(0.05)win32api.keybd_event(0x51, MapVirtualKey(0x51, 0), win32con.KEYEVENTF_KEYUP, 0)#全局变量q赋值为0,监控函数又可以介入了q = 0print('自动按q')def press_r():global rwhile True:#消费一个r信号量semaphorer.acquire()r = 5MapVirtualKey = ctypes.windll.user32.MapVirtualKeyA# time.sleep(0.1)for i in range(5):win32api.keybd_event(0x52, MapVirtualKey(0x52, 0), 0, 0)time.sleep(0.05)win32api.keybd_event(0x52, MapVirtualKey(0x52, 0), win32con.KEYEVENTF_KEYUP, 0)r = 4print('自动按r')# 运行进程
t1 = Listener(on_press=on_pressq)
t2 = Listener(on_press=on_pressr)
t3 = threading.Thread(target=press_q, name='sendThreadq')
t5 = threading.Thread(target=press_r, name='sendThreadr')
t1.start()
t2.start()
t3.start()
t5.start()os.system("pause")

通过信号量来稳定连点次数,通过全局变量来控制监控函数(信号量的生产者)的介入(虽然仍然有监测行为,但是却没有赋值以及信号量生产行为),减少了控制函数和连点函数之间的交叉干扰,删掉了没有必要的按键抬起监测函数。再来实验一下(只按一下q):


效果不错,而且不会出现松开q键仍然会继续连点的情况。

ps.欢迎拍砖,对多线程不太熟悉,如果有更好的解决方案请留言。

利用python实现键盘连点器相关推荐

  1. python类加载器_利用Python反序列化运行加载器实现免杀

    前言 前几天在看Python的shellcode加载器,在网上找了一个,结果加载器自身就过不了火绒,测试发现是火绒对关键语句进行了识别. 所以我们要想办法去掉加载器中明显的特征. 原理及实现 在绕过静 ...

  2. php5.5 反序列化利用工具_利用Python反序列化运行加载器实现免杀

    前言 前几天在看Python的shellcode加载器,在网上找了一个,结果加载器自身就过不了火绒,测试发现是火绒对关键语句进行了识别. 所以我们要想办法去掉加载器中明显的特征. 原理及实现 在绕过静 ...

  3. 利用Python制作简易的点赞器

    目录 一.点赞机器人核心逻辑 二.代码层级的实现 模拟登录 点赞器 一.点赞机器人核心逻辑 模拟点击操作,触发点赞,喜欢等操作. 实现点赞操作前,还有一步重要的代码实现,模拟登录. 因此,点赞机器人的 ...

  4. 利用Python实现键盘操控小车、通过树莓派GPIO使用python操控小车(树莓派小车、树莓派+Python+LN298操控小车)

    (树莓派小车.树莓派+Python+LN298操控小车) 一.Python代码获取键盘实时键位 二.树莓派自带GPIO控制电机 大功告成!编写不易,大家成功后点个关注or赞谢谢~~ 一.Python代 ...

  5. python布局管理数据_利用python创建窗口-布局管理器(五)

    下面的程序是对之前的创建的窗口进行进一步改进,即利用布局管理器对窗口进行自动的管理. 在这里,Panel用于创建画布,BoxSizer用于创建管理器,wx.EXPAND表示可以拓展,border表示边 ...

  6. 【芝麻IP代理】如何利用Python实现简易音乐播放器

    [芝麻IP代理]Python图形界面 图形界面(GUI),即以图形方式显示计算机操作用户界面. Python支持第三方库来实现图形界面,例如Tk.wxWidgets及Qt等.其中,Python自带的库 ...

  7. 利用python制作语音变声器,这么牛的技术还不来学?

    APP 也有文字转换为语音的功能,虽然听起来很别扭,但是基本能解决长辈们看不清文字或者眼睛疲劳,通过文字转换为语音来获取信息. 我们用 Python 能否实现文字转语音呢,可以的,百度有个语音接口,可 ...

  8. 小哥哥你有98K吗?利用Python制作一款多功能变声器!

    前言 好吧,关于这句小哥哥你有98K吗?出自别人口中经常说的玩笑话,我也略懂一些游戏嘛.不过不常玩,废话不多说,开始咱们今天的教程,非常简单! 利用Python制作一款多功能变声器! 咱们首先登陆百度 ...

  9. 基于朴素贝叶斯分类器的西瓜数据集 2.0 预测分类_第十章:利用Python实现朴素贝叶斯模型

    免责声明:本文是通过网络收集并结合自身学习等途径合法获取,仅作为学习交流使用,其版权归出版社或者原创作者所有,并不对涉及的版权问题负责.若原创作者或者出版社认为侵权,请联系及时联系,我将立即删除文章, ...

  10. python实现按键精灵的功能_利用Python实现Windows下的鼠标键盘模拟的实例代码

    本文介绍了利用Python实现Windows下的鼠标键盘模拟的实例代码,分享给大家 本来用按键精灵是可以实现我的需求,而且更简单,但既然学python ,就看一下呗. 依赖: pip install ...

最新文章

  1. 深度学习-我们为什么需要BN(Batch Normalization)?
  2. RabbitMQ消息可靠性分析和应用
  3. win7录制系统声音 加入立体声混音 camtasia recorder录屏
  4. Mysql修改字段名和长度_mysql中修改表字段名/字段长度/字段类型详解
  5. 不安装cudnn可不可以_Linux非root用户如何优雅的安装cuda和cudnn
  6. Docker学习文档之三 其他相关-参考
  7. 串口(USART)通信-串口通讯协议简介
  8. oc 协议 回调 静态成员_ios – 在一个块中,__block变量和静态变量之间的实际区别是什么?...
  9. MyBatis 动态 SQL(认真看看, 以后写 SQL 就爽多了)
  10. 【其他】使win7尽量少占用C盘空间
  11. 汇编语言 王爽 第四版 第二章 检测点2.1
  12. Mip-NeRF:抗混叠的多尺度神经辐射场ICCV2021
  13. mysql 字段 符号_mysql数据库字段带符号的问题
  14. H5/web前端工程简历中的项目经验
  15. 使用微服务架构重构支付网关
  16. 电脑WLAN/WIFI搜索不到网络
  17. 怎么制作动态图片?教你三步制作GIF图片?
  18. VUE之高德地图轨迹绘制与轨迹回放
  19. ICH1/ICH2/ICH3/ICH4/ICH5/ICH6/ICH7/ICH8/ICH9的区别和联系
  20. openssl私有CA证书签发与单双向认证

热门文章

  1. 各种开源数据库同步工具汇总
  2. AdminLTE登录页设置背景图片
  3. java 柱状图 宽度_Java 创建Excel图表
  4. linux ahci 驱动下载,linux ahci驱动分析 SylixOS中AHCI驱动框架分析
  5. Julia之初体验(一)下载与安装
  6. 今日头条阅读量怎么刷_自动刷今日头条阅读量 头条号自己刷阅读量
  7. 进程通信方式总结与盘点
  8. 进程通信的几种方式及其各自优缺点
  9. 矩阵求导法则,梯度求导方式
  10. 在读服务器端的备份说明文件错误,3dmax保存文件时出错,提示“无法创建备份文件”的原因和解决方法...