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

使用pynput的mouse.Listener()时如何解决鼠标卡顿问题?

解决pynput鼠标监听时的卡顿问题

你的鼠标卡顿根本不是pynput的必然结果,核心原因是主线程被无限循环里的全屏截图+OpenCV显示操作占满了CPU,导致系统无法及时响应鼠标事件。pynput的监听线程是后台运行的,但主线程CPU跑满后,系统分配给鼠标事件处理的资源被挤压,自然出现卡顿。

具体解决方案

把耗时的截图+显示逻辑从主线程剥离,放到单独线程中,并添加帧率控制,减少不必要的资源占用:

from PIL import ImageGrab
import cv2
import numpy as np
from pynput import mouse
import threading
import time

side_button_held = False
# 用事件对象控制截图线程的启停
screenshot_trigger = threading.Event()

def on_click(x, y, button, pressed):
    global side_button_held
    if button == mouse.Button.x2 and pressed:
        side_button_held = True
        screenshot_trigger.set()  # 开启截图
        print("侧键已按下")
    elif button == mouse.Button.x2:
        side_button_held = False
        screenshot_trigger.clear()  # 停止截图
        cv2.destroyWindow("Screen")  # 及时销毁窗口释放资源
        print("侧键已松开")

def screenshot_task():
    # 控制截图帧率,每秒30帧足够,避免无意义的高频操作
    target_fps = 30
    frame_interval = 1 / target_fps
    
    while True:
        if screenshot_trigger.is_set():
            start_time = time.time()
            
            # 截图与格式转换
            screenshot = ImageGrab.grab(bbox=None)
            img = np.array(screenshot)
            rgb_img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
            
            cv2.imshow("Screen", rgb_img)
            cv2.waitKey(1)
            
            # 计算剩余时间,保证帧率稳定
            elapsed = time.time() - start_time
            if elapsed < frame_interval:
                time.sleep(frame_interval - elapsed)
        else:
            # 未触发时低负载等待
            time.sleep(0.01)

# 启动截图线程(守护线程,随主程序退出)
screenshot_thread = threading.Thread(target=screenshot_task, daemon=True)
screenshot_thread.start()

# 启动鼠标监听
listener = mouse.Listener(on_click=on_click)
listener.start()

# 主线程保持运行,等待监听线程结束
listener.join()

优化说明

  1. 线程分离:把截图和显示逻辑放到独立线程,主线程只负责处理鼠标事件,不会被CPU密集型操作阻塞。
  2. 帧率控制:固定30帧的截图频率,既保证显示流畅,又避免无限制占用CPU。
  3. 资源清理:释放侧键时及时销毁OpenCV窗口,避免残留资源占用。

额外优化建议

  • 若追求更低的CPU占用,可以替换ImageGrab为mss库,它的截图效率更高。
  • 如果不需要全屏截图,给grab()指定bbox参数缩小截图区域,进一步降低资源消耗。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.11 20:40:12