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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.23 01:02:46