Python中如何锁定鼠标光标位置并追踪其理论移动轨迹?
锁定鼠标位置并追踪位移的实现方案
你的需求核心是阻止光标实际移动,同时捕获鼠标的原始移动增量来计算虚拟位置,不能用强制移回光标这种取巧方式。下面分平台给出具体实现:
Windows 平台(Python 实现)
通过 pywin32 注册低级鼠标钩子,拦截鼠标移动事件的系统默认处理,同时提取移动增量计算虚拟位置:
import win32api import win32con import win32gui import pythoncom from ctypes import windll, CFUNCTYPE, c_int, c_void_p, Structure, c_long # 虚拟位置初始值(以锁定时的实际光标位置为基准) virtual_x, virtual_y = 0, 0 hook_handle = None # 定义钩子回调函数类型 HookProc = CFUNCTYPE(c_int, c_int, c_int, c_void_p) # 对应Windows的MSLLHOOKSTRUCT结构体 class MSLLHOOKSTRUCT(Structure): _fields_ = [("pt", win32gui.POINT), ("mouseData", c_long), ("flags", c_int), ("time", c_int), ("dwExtraInfo", c_void_p)] def mouse_hook(nCode, wParam, lParam): global virtual_x, virtual_y # 只处理鼠标移动事件 if nCode >= 0 and wParam == win32con.WM_MOUSEMOVE: hook_struct = MSLLHOOKSTRUCT.from_address(lParam) # 获取相对位移(dx/dy相对于上一次事件的移动量) delta_x = hook_struct.pt.x - virtual_x delta_y = hook_struct.pt.y - virtual_y # 更新虚拟位置 virtual_x += delta_x virtual_y += delta_y print(f"Mouse would be at {virtual_x}, {virtual_y} if it wasn't locked.") # 返回1阻止事件传递给系统,光标不会移动 return 1 # 其他事件正常传递 return windll.user32.CallNextHookEx(hook_handle, nCode, wParam, lParam) def main(): global hook_handle, virtual_x, virtual_y # 获取初始光标位置作为虚拟位置起点 x, y = win32gui.GetCursorPos() virtual_x, virtual_y = x, y # 注册全局低级鼠标钩子 hook_proc = HookProc(mouse_hook) hook_handle = windll.user32.SetWindowsHookExW(win32con.WH_MOUSE_LL, hook_proc, win32api.GetModuleHandle(None), 0) if not hook_handle: print("钩子注册失败") return # 消息循环维持程序运行 while True: pythoncom.PumpWaitingMessages() if __name__ == "__main__": main()
注意事项
- 安装依赖:
pip install pywin32 - 需以管理员权限运行程序,否则无法注册全局钩子
- 终止程序可使用
Ctrl+C
Linux 平台(Python 实现)
使用 python-xlib 捕获X11鼠标事件,通过抓取指针阻止光标移动,同时计算位移增量:
from Xlib import X, display # 虚拟位置初始值 virtual_x, virtual_y = 0, 0 # 记录上一次鼠标绝对位置 last_x, last_y = 0, 0 def main(): global virtual_x, virtual_y, last_x, last_y d = display.Display() root = d.screen().root # 获取初始光标位置 pointer_info = root.query_pointer() x, y = pointer_info.root_x, pointer_info.root_y virtual_x, virtual_y = x, y last_x, last_y = x, y # 抓取鼠标,拦截所有指针事件 root.grab_pointer( True, X.ButtonPressMask | X.ButtonReleaseMask | X.PointerMotionMask, X.GrabModeAsync, X.GrabModeAsync, 0, 0, X.CurrentTime ) # 监听鼠标移动事件 while True: event = d.next_event() if event.type == X.MotionNotify: # 计算相对位移 delta_x = event.root_x - last_x delta_y = event.root_y - last_y last_x = event.root_x last_y = event.root_y # 更新虚拟位置 virtual_x += delta_x virtual_y += delta_y print(f"Mouse would be at {virtual_x}, {virtual_y} if it wasn't locked.") # 强制将光标移回初始位置(避免因系统特性导致的微小偏移) root.warp_pointer(x, y) d.sync() d.close() if __name__ == "__main__": main()
注意事项
- 安装依赖:
pip install python-xlib - 需确保程序有X11输入访问权限,部分桌面环境可能需调整系统设置
核心逻辑说明
- 两种方案均通过拦截鼠标事件的系统默认处理流程阻止光标移动,而非强制将光标移回原位置
- 位移计算基于鼠标的原始移动增量,累计得到虚拟位置,完全匹配需求
内容的提问来源于stack exchange,提问作者yilmaz
相关产品推荐
相关产品推荐

