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

自动移动鼠标无法触发按钮悬停状态的技术求助

问题

通过代码将光标移动到按钮位置后,光标无法被系统识别为处于按钮上方,保持普通状态无法触发点击;但手动对鼠标进行微小移动后,光标就能切换至就绪状态,按钮可正常点击。

已尝试的解决方式包括:补间移动(tweening)+左右抖动、边缘绕圈移动、随机曲线移动、正弦曲线移动、线性移动、按钮上微移动等,但均未解决问题。

现有Python代码如下:

import pyautogui
import time
import random

# Define constants
BREAKTHROUGH_COLOR = (248, 248, 248)
WAIT_TIME_INITIAL = 10
WAIT_TIME_BREAKTHROUGH = 20
WAIT_TIME_BETWEEN_CLICKS = 0.1

# Initial mouse position
INITIAL_POSITION = (956, 644)

# Meditate button position
MEDITATE_POSITION = (960, 980)

def tween_to_position(start_position, end_position, tween_time):
    x_start, y_start = start_position
    x_end, y_end = end_position
    
    steps = int(tween_time / 0.05)  # Number of steps based on a 0.05s interval
    
    for step in range(steps):
        progress = step / steps
        x = x_start + int((x_end - x_start) * progress)
        y = y_start + int((y_end - y_start) * progress)
        
        # Add small random jitters to the left and right
        x += random.randint(-5, 5)
        
        pyautogui.moveTo(x, y, duration=0.05)

def common_actions():
    # Common actions button position
    COMMON_ACTIONS_POSITION = (150, 20)
    
    # Tweening
    tween_to_position(COMMON_ACTIONS_POSITION, (75, 20), tween_time=2)
    
    time.sleep(1)  # Add a delay before the click
    pyautogui.click(75, 20, clicks=3, interval=WAIT_TIME_BETWEEN_CLICKS)

while True:
    time.sleep(WAIT_TIME_INITIAL)

    if pyautogui.pixel(*INITIAL_POSITION) == BREAKTHROUGH_COLOR:
        print("Breakthrough ready")
        
        # Tweening for the breakthrough button
        tween_to_position((956, 400), INITIAL_POSITION, tween_time=2)
        
        pyautogui.click(*INITIAL_POSITION, clicks=5, interval=WAIT_TIME_BETWEEN_CLICKS)  # Increase the number of clicks
        print("Waiting for breakthrough")
        time.sleep(WAIT_TIME_BREAKTHROUGH)
        print("Meditating")
        
        # Tweening for the meditation button
        tween_to_position((960, 900), MEDITATE_POSITION, tween_time=2)
        
        pyautogui.click(*MEDITATE_POSITION, clicks=5, interval=WAIT_TIME_BETWEEN_CLICKS)  # Increase the number of clicks

    else:
        print("Not ready")
        common_actions()
解决方案

方案1:模拟手动微小偏移触发hover事件

很多GUI系统(尤其是游戏或自定义UI)依赖鼠标实时移动事件触发hover状态,而非仅检测静态坐标。可在到达目标位置后,做极小偏移再移回,同时给系统留识别时间:

def ensure_hover(position):
    x, y = position
    # 向右下移动1像素触发移动事件
    pyautogui.moveTo(x+1, y+1, duration=0.01)
    # 移回原按钮位置
    pyautogui.moveTo(x, y, duration=0.01)
    # 等待系统识别hover状态
    time.sleep(0.05)

修改原代码中的点击逻辑,在pyautogui.click前调用该函数:

# 突破按钮处理
tween_to_position((956, 400), INITIAL_POSITION, tween_time=2)
ensure_hover(INITIAL_POSITION)
pyautogui.click(*INITIAL_POSITION, clicks=5, interval=WAIT_TIME_BETWEEN_CLICKS)

# 冥想按钮处理同理
tween_to_position((960, 900), MEDITATE_POSITION, tween_time=2)
ensure_hover(MEDITATE_POSITION)
pyautogui.click(*MEDITATE_POSITION, clicks=5, interval=WAIT_TIME_BETWEEN_CLICKS)

方案2:使用相对移动替代绝对定位微调

用pyautogui.moveRel()做最后阶段的微小相对移动,强制触发系统的鼠标移动检测:

在到达目标位置后添加以下代码:

# 向右移动2像素再移回
pyautogui.moveRel(2, 0, duration=0.02)
pyautogui.moveRel(-2, 0, duration=0.02)
# 短暂等待识别
time.sleep(0.03)

方案3:模拟真实鼠标的"停留+微动"行为

部分UI会通过鼠标停留时长+微小位移判定hover状态,可在目标位置做多次小范围随机抖动:

def simulate_real_hover(position, duration=0.5):
    x, y = position
    start_time = time.time()
    while time.time() - start_time < duration:
        # 生成随机微小偏移
        dx = random.randint(-1, 1)
        dy = random.randint(-1, 1)
        pyautogui.moveTo(x+dx, y+dy, duration=0.02)
        time.sleep(0.01)
    # 最后回到按钮准确位置
    pyautogui.moveTo(x, y, duration=0.01)

调用方式同方案1,在点击前执行simulate_real_hover(目标位置)即可。

方案4:绕过移动,直接发送点击事件(极端情况)

如果上述方法均无效,说明系统hover检测依赖硬件级鼠标事件,可尝试直接在目标坐标发送点击命令,跳过移动步骤:

# 替换原move+click逻辑,直接模拟按下+松开鼠标
pyautogui.mouseDown(*INITIAL_POSITION)
time.sleep(0.05)
pyautogui.mouseUp(*INITIAL_POSITION)

内容的提问来源于stack exchange,提问作者OB Wan Kenobi

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.28 03:00:01