如何用Python实现键盘模拟触摸屏?代码问题排查与优化
键盘模拟触屏操作的Python实现优化方案
需求说明
- 部分游戏无法通过Bluestacks等安卓模拟器登录(因无法自动填充验证码),需在PC端用键盘模拟触屏操作
- 按键与触摸点对应关系:
w= 前向(顶部中心)q= 左上角e= 右上角a= 左方s= 点击或中心位置d= 右方z= 左下角x= 后向(底部中心)c= 右下角
- 核心需求:
- 在Windows系统实现9个触摸点的点击操作
- 支持组合键(如
s+d)模拟滑动功能 - 修复原有代码中方向控制函数无法同时运行的问题
现有代码问题分析
原有代码中LtRt()和UpDown()均为无限循环函数,主线程顺序调用时,第一个函数会持续占用线程资源,导致第二个函数永远无法执行。此外,代码未实现指定的触摸点点击和组合键滑动逻辑。
优化后的代码实现
import win32api import pyautogui as pg import keyboard as kb import threading from time import sleep # 基于屏幕分辨率自动计算9个触摸点坐标(可直接修改为固定坐标适配特定窗口) SCREEN_WIDTH, SCREEN_HEIGHT = pg.size() TOUCH_POINTS = { 'w': (SCREEN_WIDTH // 2, SCREEN_HEIGHT // 4), 'q': (SCREEN_WIDTH // 4, SCREEN_HEIGHT // 4), 'e': (SCREEN_WIDTH * 3 // 4, SCREEN_HEIGHT // 4), 'a': (SCREEN_WIDTH // 4, SCREEN_HEIGHT // 2), 's': (SCREEN_WIDTH // 2, SCREEN_HEIGHT // 2), 'd': (SCREEN_WIDTH * 3 // 4, SCREEN_HEIGHT // 2), 'z': (SCREEN_WIDTH // 4, SCREEN_HEIGHT * 3 // 4), 'x': (SCREEN_WIDTH // 2, SCREEN_HEIGHT * 3 // 4), 'c': (SCREEN_WIDTH * 3 // 4, SCREEN_HEIGHT * 3 // 4) } def handle_directional_movement(): """处理WASD方向键的连续移动逻辑""" x, y = win32api.GetCursorPos() move_step_x = 60 move_step_y = 40 while True: # 松开方向键时重置坐标基准 if not kb.is_pressed('w') and not kb.is_pressed('s'): y = win32api.GetCursorPos()[1] if not kb.is_pressed('a') and not kb.is_pressed('d'): x = win32api.GetCursorPos()[0] # 上下移动控制 if kb.is_pressed('w'): y -= move_step_y pg.moveTo(x, y, duration=0.0) if kb.is_pressed('s'): y += move_step_y pg.moveTo(x, y, duration=0.0) # 左右移动控制 if kb.is_pressed('a'): x -= move_step_x pg.moveTo(x, y, duration=0.0) if kb.is_pressed('d'): x += move_step_x pg.moveTo(x, y, duration=0.0) sleep(0.01) # 降低CPU占用 def handle_touch_clicks_and_swipes(): """处理单点触摸点击与组合键滑动逻辑""" while True: # 单点触摸点击处理 for key, pos in TOUCH_POINTS.items(): if kb.is_pressed(key) and key not in ['w','a','s','d']: pg.click(pos) sleep(0.2) # 防止重复触发点击 # 组合键滑动示例:s+d 模拟中心向右滑动 if kb.is_pressed('s') and kb.is_pressed('d'): pg.dragTo(TOUCH_POINTS['d'][0], TOUCH_POINTS['d'][1], duration=0.2, button='left') # s+a 模拟中心向左滑动 if kb.is_pressed('s') and kb.is_pressed('a'): pg.dragTo(TOUCH_POINTS['a'][0], TOUCH_POINTS['a'][1], duration=0.2, button='left') # w+s 模拟中心向下滑动 if kb.is_pressed('w') and kb.is_pressed('s'): pg.dragTo(TOUCH_POINTS['x'][0], TOUCH_POINTS['x'][1], duration=0.2, button='left') sleep(0.1) def main(): # 创建守护线程,避免主程序退出时残留线程 move_thread = threading.Thread(target=handle_directional_movement, daemon=True) click_swipe_thread = threading.Thread(target=handle_touch_clicks_and_swipes, daemon=True) move_thread.start() click_swipe_thread.start() # 主程序等待退出信号(按Esc键终止) print("程序已启动,按Esc键退出") kb.wait('esc') if __name__ == "__main__": main()
代码关键优化点
- 多线程解决阻塞:通过
threading.Thread创建两个独立线程,分别处理方向移动和触摸操作,避免单线程下的函数阻塞问题。 - 自适应触摸点:基于屏幕分辨率自动计算触摸点坐标,也可直接修改为固定坐标适配特定游戏窗口。
- 组合键滑动实现:通过检测多按键按下状态,模拟触屏滑动动作,可根据需求扩展更多组合逻辑。
- 性能优化:添加
sleep控制循环频率,降低CPU资源占用。
内容的提问来源于stack exchange,提问作者Gilbert Jackob
相关产品推荐
相关产品推荐

