You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python自动点击器功能异常及热键触发问题求助

Python自动点击器功能异常及热键触发问题求助

我正在尝试制作一个自动点击器,它需要先检查点击器是否启用,然后检查用户是否按住鼠标左键。如果满足条件,程序会在一定延迟范围内点击。当用户释放左键时,自动点击应该停止。我目前的代码可以正常启用和禁用,但当我按住鼠标按钮时,只能得到1-2次点击,然后就停止了。

第二个问题是,使用自动点击器的热键时,我必须不按任何其他键才能激活热键。例如,在玩游戏时,我无法一边移动(按其他键)一边启用或禁用自动点击器。

如果有人能解决这两个问题,我将非常感谢任何建议。


我来帮你分析这两个问题并给出修复方案:

问题1:按住左键仅触发1-2次点击就停止

核心原因:

  1. 旧版mouse_eventAPI模拟的点击会干扰GetAsyncKeyState的检测——当程序模拟左键松开时,会让检测函数误以为用户已经松开了左键,直接退出循环。
  2. 嵌套循环逻辑有缺陷:一旦单次检测到左键状态为False(哪怕是模拟点击导致的),就会完全退出内部触发逻辑,必须等用户松开再按下左键才会重新启动。

修复方案:

  • 改用Windows推荐的SendInputAPI模拟输入,它不会干扰物理按键的状态检测;
  • 重构循环逻辑,将嵌套循环改为单循环,每次迭代都重新检查启用状态和用户的左键按压状态,避免单次检测错误导致停止。

问题2:热键需松开其他键才能触发

核心原因:
keyboard.add_hotkey默认采用"严格匹配"逻辑——只有当目标键单独按下时才会触发,其他按键按住时会被忽略,这在游戏场景下非常受限。

修复方案:
改用keyboard.on_press_key监听按键事件,它会直接响应目标键的按下动作,无论你是否按住其他按键。


修改后的完整代码

import ctypes
import time
import threading
import random
import keyboard

# Constants for Windows API mouse events
MOUSEEVENTF_LEFTDOWN = 0x0002
MOUSEEVENTF_LEFTUP = 0x0004
VK_LBUTTON = 0x01  # Virtual key code for the left mouse button

# Windows API functions
user32 = ctypes.windll.user32

# 定义SendInput所需的结构体(替代旧版mouse_event)
class MOUSEINPUT(ctypes.Structure):
    _fields_ = [
        ("dx", ctypes.c_long),
        ("dy", ctypes.c_long),
        ("mouseData", ctypes.c_uint),
        ("dwFlags", ctypes.c_uint),
        ("time", ctypes.c_uint),
        ("dwExtraInfo", ctypes.c_void_p)
    ]

class INPUT(ctypes.Structure):
    _fields_ = [
        ("type", ctypes.c_uint),
        ("mi", MOUSEINPUT)
    ]

INPUT_MOUSE = 0

def send_mouse_input(flags):
    """使用SendInput模拟鼠标输入,更可靠且不干扰物理按键检测"""
    mi = MOUSEINPUT(0, 0, 0, flags, 0, None)
    inp = INPUT(INPUT_MOUSE, mi)
    user32.SendInput(1, ctypes.byref(inp), ctypes.sizeof(inp))

def click():
    """模拟一次完整的左键点击"""
    send_mouse_input(MOUSEEVENTF_LEFTDOWN)
    send_mouse_input(MOUSEEVENTF_LEFTUP)

def is_left_mouse_button_pressed():
    """检测用户物理左键是否按住"""
    return user32.GetAsyncKeyState(VK_LBUTTON) & 0x8000 != 0

# Control variables
enabled = False  # Toggle for enabling/disabling the clicker

# Hotkeys
ENABLE_KEY = 'g'  # Press 'g' to enable/disable auto-clicking
EXIT_KEY = '0'    # Press '0' to exit

def clicker():
    """重构后的点击循环逻辑,避免单次检测错误导致停止"""
    while True:
        if enabled and is_left_mouse_button_pressed():
            click()
            # 随机延迟,同时降低被反作弊系统识别的风险
            time.sleep(random.uniform(0.05, 0.3))
        # 缩短非点击状态的延迟,提高响应速度
        time.sleep(0.001)

def toggle_clicking():
    global enabled
    enabled = not enabled
    print(f"Auto-clicker {'enabled' if enabled else 'disabled'}")

# Start clicking thread
clicking_thread = threading.Thread(target=clicker, daemon=True)
clicking_thread.start()

# 设置热键:改用on_press_key,支持按住其他键时触发
keyboard.on_press_key(ENABLE_KEY, lambda event: toggle_clicking(), suppress=False)

# Wait for exit key
keyboard.wait(EXIT_KEY)

额外说明

  1. SendInput的优势:作为Windows官方推荐的输入模拟API,它的行为更接近物理输入,不会干扰对用户实际按键的检测,同时也更不容易被游戏反作弊系统识别。
  2. 循环逻辑优化:单循环每次都会重新检查状态,哪怕某次检测因为临时干扰返回False,下一次迭代依然会响应用户的按住操作。
  3. 热键触发优化:on_press_key直接监听目标键的按下事件,游戏中按住WASD等移动键时,依然可以正常触发自动点击器的启停。

备注:内容来源于stack exchange,提问作者Matteo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.13 18:53:09