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
相关产品推荐
相关产品推荐

