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

mouse.is_pressed始终返回True的问题排查求助

问题:鼠标X2按键按住时长检测不符合预期

我给鼠标X2按键的按下事件加了钩子,想检测按键按住的时长。预期is_pressed()在按住时返回True,2秒前松开就返回False,从而更新状态跳出循环,但实际松开后它始终返回True。我猜测是X2的鼠标按下事件同步运行,导致is_pressed('x2')一直返回True,希望得到确认。拆分按下和抬起事件加全局计时器能正常工作,但我想避免这种拆分。

代码示例

def X2_buttonDown():
    startedAt = round(time.time() * 1000)
    buttonIsDown = mouse.is_pressed(mouse.X2)

    while buttonIsDown and (round(time.time() * 1000) - startedAt) <= 2000:
        print("still down. sleeping")
        time.sleep(0.1)
        buttonIsDown = mouse.is_pressed(mouse.X2)
        print(mouse.is_pressed(mouse.X2))

    if buttonIsDown:
        print("button was held")
    else:
        print("button was let go before 2 secs")

mouse.on_button(X2_buttonDown, args = (), buttons = [mouse.X2], types = [mouse.DOWN])     

快速点击后的输出

still down. sleeping
True
still down. sleeping
True
still down. sleeping
True
still down. sleeping
True
still down. sleeping
True
button was held

解答

你的猜测完全正确,问题出在mouse库的事件处理机制上:

  • 当mouse.DOWN事件触发时,你的回调函数X2_buttonDown()是在事件监听的单线程上下文里同步执行的。
  • 你在循环里用time.sleep(0.1)会直接阻塞整个事件监听线程,导致后续的X2按键抬起事件根本无法被处理。系统的输入状态一直停留在“按下”,所以is_pressed()始终返回True。

不用拆分事件的解决方法

直接用mouse.wait()来监听抬起事件并设置超时,让库内部处理事件队列,避免手动循环阻塞:

def X2_buttonDown():
    # 等待X2抬起事件,超时时间设为2秒
    pressed_until = mouse.wait(mouse.X2, mouse.UP, timeout=2)
    if pressed_until is None:
        print("button was held")
    else:
        print("button was let go before 2 secs")

mouse.on_button(X2_buttonDown, args=(), buttons=[mouse.X2], types=[mouse.DOWN])

这个方法的核心是让mouse库负责事件监听逻辑,它会在等待期间处理其他输入事件,不会像你的原代码那样阻塞线程,因此能正确捕捉到按键抬起的状态。


内容的提问来源于stack exchange,提问作者user2368631

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.19 06:17:33