跳转到主要内容

监控和控制用户输入设备

项目描述

pynput

这个库允许您控制和监控输入设备。

目前支持鼠标和键盘的输入和监控。

有关完整文档,请参阅此处

控制鼠标

使用pynput.mouse.Controller如下所示

from pynput.mouse import Button, Controller

mouse = Controller()

# Read pointer position
print('The current pointer position is {0}'.format(
    mouse.position))

# Set pointer position
mouse.position = (10, 20)
print('Now we have moved it to {0}'.format(
    mouse.position))

# Move pointer relative to current position
mouse.move(5, -5)

# Press and release
mouse.press(Button.left)
mouse.release(Button.left)

# Double click; this is different from pressing and releasing
# twice on macOS
mouse.click(Button.left, 2)

# Scroll two steps down
mouse.scroll(0, 2)

监控鼠标

使用 pynput.mouse.Listener 如下所示

from pynput import mouse

def on_move(x, y):
    print('Pointer moved to {0}'.format(
        (x, y)))

def on_click(x, y, button, pressed):
    print('{0} at {1}'.format(
        'Pressed' if pressed else 'Released',
        (x, y)))
    if not pressed:
        # Stop listener
        return False

def on_scroll(x, y, dx, dy):
    print('Scrolled {0} at {1}'.format(
        'down' if dy < 0 else 'up',
        (x, y)))

# Collect events until released
with mouse.Listener(
        on_move=on_move,
        on_click=on_click,
        on_scroll=on_scroll) as listener:
    listener.join()

# ...or, in a non-blocking fashion:
listener = mouse.Listener(
    on_move=on_move,
    on_click=on_click,
    on_scroll=on_scroll)
listener.start()

鼠标监听器是一个 threading.Thread,所有回调都会从这个线程中调用。

从任何地方调用 pynput.mouse.Listener.stop,或者在回调中抛出 StopException 或返回 False 来停止监听器。

当使用上面的非阻塞版本时,当前线程将继续执行。这可能在与其他包含主循环的GUI框架集成时是必要的,但当从脚本运行时,这会导致程序立即终止。

鼠标监听器线程

在某些平台上,监听器回调会直接从操作系统线程调用,尤其是在 Windows 上。

这意味着不应该在回调中调用长时间运行的过程和阻塞操作,因为这可能会冻结所有进程的输入。

一个可能的解决方案是将传入的消息派发到队列中,然后让另一个线程来处理它们。

处理鼠标监听器错误

如果回调处理程序抛出异常,监听器将被停止。由于回调在专用线程中运行,异常不会自动重新抛出。

要通知回调错误,请在监听器实例上调用 Thread.join

from pynput import mouse

class MyException(Exception): pass

def on_click(x, y, button, pressed):
    if button == mouse.Button.left:
        raise MyException(button)

# Collect events until released
with mouse.Listener(
        on_click=on_click) as listener:
    try:
        listener.join()
    except MyException as e:
        print('{0} was clicked'.format(e.args[0]))

切换鼠标监听器的事件监听

一旦调用过 pynput.mouse.Listener.stop,监听器就无法重新启动,因为监听器是 threading.Thread 的实例。

如果您的应用程序需要切换监听事件,您必须添加一个内部标志来忽略不需要的事件,或者在重新开始监听时创建一个新的监听器。

鼠标监听器的同步事件监听

为了简化脚本编写,通过实用程序类 pynput.mouse.Events 支持同步事件监听。该类支持以非阻塞方式读取单个事件,以及遍历所有事件。

要读取单个事件,使用以下代码

from pynput import mouse

# The event listener will be running in this block
with mouse.Events() as events:
    # Block at most one second
    event = events.get(1.0)
    if event is None:
        print('You did not interact with the mouse within one second')
    else:
        print('Received event {}'.format(event))

要遍历鼠标事件,使用以下代码

from pynput import mouse

# The event listener will be running in this block
with mouse.Events() as events:
    for event in events:
        if event.button == mouse.Button.right:
            break
        else:
            print('Received event {}'.format(event))

请注意,迭代方法不支持非阻塞操作,因此它将至少等待一个鼠标事件。

事件将是 pynput.mouse.Events 中发现的内部类的实例。

确保在 Windows 上监听器和控制器之间保持一致的坐标

Windows 的最新版本支持在系统缩放超过 100% 时运行旧应用程序进行缩放。这允许旧应用程序进行缩放,尽管外观模糊,但避免了小到无法使用的用户界面。

遗憾的是,这种缩放不一致地应用于鼠标监听器和控制器:监听器将收到物理坐标,但控制器必须使用缩放坐标。

可以通过告诉 Windows 您的应用程序是 DPI 感知的来解决这个问题。这是一个进程全局设置,所以 _pynput_ 无法自动执行。启用 DPI 感知,请运行以下代码

import ctypes


PROCESS_PER_MONITOR_DPI_AWARE = 2

ctypes.windll.shcore.SetProcessDpiAwareness(PROCESS_PER_MONITOR_DPI_AWARE)

控制键盘

像这样使用 pynput_robocorp.keyboard.Controller

from pynput_robocorp.keyboard import Key, Controller

keyboard = Controller()

# Press and release space
keyboard.press(Key.space)
keyboard.release(Key.space)

# Type a lower case A; this will work even if no key on the
# physical keyboard is labelled 'A'
keyboard.press('a')
keyboard.release('a')

# Type two upper case As
keyboard.press('A')
keyboard.release('A')
with keyboard.pressed(Key.shift):
    keyboard.press('a')
    keyboard.release('a')

# Type 'Hello World' using the shortcut type method
keyboard.type('Hello World')

监控键盘

像这样使用 pynput_robocorp.keyboard.Listener

from pynput import keyboard

def on_press(key):
    try:
        print('alphanumeric key {0} pressed'.format(
            key.char))
    except AttributeError:
        print('special key {0} pressed'.format(
            key))

def on_release(key):
    print('{0} released'.format(
        key))
    if key == keyboard.Key.esc:
        # Stop listener
        return False

# Collect events until released
with keyboard.Listener(
        on_press=on_press,
        on_release=on_release) as listener:
    listener.join()

# ...or, in a non-blocking fashion:
listener = keyboard.Listener(
    on_press=on_press,
    on_release=on_release)
listener.start()

键盘监听器是一个 threading.Thread,所有回调都会从这个线程中调用。

从任何地方调用 pynput_robocorp.keyboard.Listener.stop,或者在回调中抛出 StopException 或返回 False 来停止监听器。

传递给回调的 key 参数是一个 pynput_robocorp.keyboard.Key,对于特殊键,是一个 pynput_robocorp.keyboard.KeyCode,对于普通字母数字键,或者对于未知键是 None

当使用上面的非阻塞版本时,当前线程将继续执行。这可能在与其他包含主循环的GUI框架集成时是必要的,但当从脚本运行时,这会导致程序立即终止。

键盘监听线程

在某些平台上,监听器回调会直接从操作系统线程调用,尤其是在 Windows 上。

这意味着不应该在回调中调用长时间运行的过程和阻塞操作,因为这可能会冻结所有进程的输入。

一个可能的解决方案是将传入的消息派发到队列中,然后让另一个线程来处理它们。

处理键盘监听错误

如果回调处理程序抛出异常,监听器将被停止。由于回调在专用线程中运行,异常不会自动重新抛出。

要通知回调错误,请在监听器实例上调用 Thread.join

from pynput import keyboard

class MyException(Exception): pass

def on_press(key):
    if key == keyboard.Key.esc:
        raise MyException(key)

# Collect events until released
with keyboard.Listener(
        on_press=on_press) as listener:
    try:
        listener.join()
    except MyException as e:
        print('{0} was pressed'.format(e.args[0]))

切换键盘监听的事件监听

一旦调用了pynput_robocorp.keyboard.Listener.stop,监听器就不能重新启动,因为监听器是threading.Thread的实例。

如果您的应用程序需要切换监听事件,您必须添加一个内部标志来忽略不需要的事件,或者在重新开始监听时创建一个新的监听器。

同步键盘监听的事件监听

为了简化脚本,同步事件监听通过工具类pynput_robocorp.keyboard.Events支持。这个类支持以非阻塞的方式读取单个事件,以及迭代所有事件。

要读取单个事件,使用以下代码

from pynput import keyboard

# The event listener will be running in this block
with keyboard.Events() as events:
    # Block at most one second
    event = events.get(1.0)
    if event is None:
        print('You did not press a key within one second')
    else:
        print('Received event {}'.format(event))

要迭代键盘事件,使用以下代码

from pynput import keyboard

# The event listener will be running in this block
with keyboard.Events() as events:
    for event in events:
        if event.key == keyboard.Key.esc:
            break
        else:
            print('Received event {}'.format(event))

请注意,迭代方法不支持非阻塞操作,因此它将至少等待一个键盘事件。

事件将是pynput_robocorp.keyboard.Events中找到的内部类的实例。

全局热键

键盘监控器的常见用例是对全局热键做出反应。由于监听器不维护任何状态,涉及多个键的热键必须将此状态存储在某个地方。

pynput为此目的提供了类pynput_robocorp.keyboard.HotKey。它包含两个用于更新状态的方法,旨在易于与键盘监听器互操作:pynput_robocorp.keyboard.HotKey.presspynput_robocorp.keyboard.HotKey.release,可以直接作为监听器回调传递。

预期用法如下

from pynput import keyboard

def on_activate():
    print('Global hotkey activated!')

def for_canonical(f):
    return lambda k: f(l.canonical(k))

hotkey = keyboard.HotKey(
    keyboard.HotKey.parse('<ctrl>+<alt>+h'),
    on_activate)
with keyboard.Listener(
        on_press=for_canonical(hotkey.press),
        on_release=for_canonical(hotkey.release)) as l:
    l.join()

这将创建一个热键,然后使用监听器来更新其状态。一旦所有指定的键同时按下,on_activate将被调用。

请注意,在传递给HotKey实例之前,键通过pynput_robocorp.keyboard.Listener.canonical传递。这是为了从键事件中移除任何修饰符状态,并使具有多个物理按钮的修饰符正常化。

pynput_robocorp.keyboard.HotKey.parse是一个便利函数,用于将快捷键字符串转换为键集合。请参阅其文档以获取更多信息。

要注册多个全局热键,请使用便利类pynput_robocorp.keyboard.GlobalHotKeys

from pynput import keyboard

def on_activate_h():
    print('<ctrl>+<alt>+h pressed')

def on_activate_i():
    print('<ctrl>+<alt>+i pressed')

with keyboard.GlobalHotKeys({
        '<ctrl>+<alt>+h': on_activate_h,
        '<ctrl>+<alt>+i': on_activate_i}) as h:
    h.join()

发行说明

v5.0.0 (2022-12-29) - 上游更新

  • 添加了上游v1.7.6的修复。

  • 使用make-release脚本。

v1.7.6 (2022-01-01) - 修复了各种错误

  • 允许将虚拟键码传递给全局热键的解析器。

  • Xorg上异步停止记录上下文。

  • 不要将None传递给objc.objc_object。感谢yejunxi

  • uinput上按下alt键时不会崩溃。感谢Caldas Lopes

  • 为从后端实现派生的监听器使用正确的选项前缀。感谢Yu Wang

v1.7.5 (2021-11-19) - 修复了各种错误

  • 修复了当监听器配置为抑制系统事件时在Xorg上的崩溃。感谢jpramosi

  • 改进了Windows上的键盘控制器处理。现在控制器更有可能与使用较低级别事件的程序一起工作。感谢bhudax

  • 更新了macOS实现以使用新的pyobjc版本。

v1.7.4 (2021-10-10) - 修复了各种错误

  • 检测macOS上是否有权限不足。感谢Dane Finlay

  • CoreFoundationQuartz中急切导入符号。感谢Ronald Oussoren

  • 改进了dumpkeys实用程序的处理。感谢Markus Niedermann

  • 删除了模糊的许可文件。

v1.7.3 (2021-02-10) - 修复了各种错误

  • 修复了Xorg上的keysym处理;并非所有组都已加载,并且从未触发了对我们内部表的回退。感谢Philipp Klaus

  • 更新了用于macOS后端的Quartz版本,以便在Big Sur上安装pynput。感谢Michael Madden

  • Windows上添加了缺失的功能键。感谢Dave Atkinson

  • 修正了macOS上鼠标控制器的滚动速度。感谢Albert Zeyer

  • 修正了Xorg的媒体键。感谢Gabriele N. Tornetta

  • 修正了文档中的参数名称。感谢Jinesi Yelizati

v1.7.2 (2020-12-21) - 修正了uinput键映射

  • 修正了uinput后端虚拟键码到字符的映射。

  • 修正了拼写错误。感谢Martin Michlmayr

  • 修正并改进了文档。

v1.7.1 (2020-08-30) - 修正了发布说明

  • 修正了Xorg对任意Unicode字符支持的感谢。

v1.7.0 (2020-08-30) - 新后端以及许多新功能和错误修复

  • 为Linux添加了一个基于uinput的键盘后端,在没有X服务器的情况下。

  • 允许在Xorg后端输入任意Unicode字符。感谢gdiShun

  • 允许通过环境变量覆盖自动选择的后端,并添加了一个虚拟后端。

  • Windows上添加了对鼠标侧键的支持。感谢danielkovarik

  • 添加了轻触键的便利方法。

  • 允许在热键中指定原始虚拟键码。

  • 当后端无法加载时,改进了错误信息。

  • 在事件字符串化中包含更多信息。

  • 修正了Events.get的返回值,以符合文档中指定的值。

  • 修正了键盘监听器在特定键盘布局中不会输入随机字符。

  • 修正了在Windows上按下某些键时的错误,操作系统报告它们已损坏,但不存在组合版本。

  • 改进了文档。

v1.6.8 (2020-02-28) - 各种修复

  • 更新了文档。

  • 修正了lint警告和测试。

  • 不要在win32函数的argtypes中使用内部类型;这会使它们在其他同一运行时中运行的代码无法调用。

  • Windows事件中包含扫描码。感谢bhudax

  • 正确应用了Windows上滚动事件值的转换。感谢DOCCA0

v1.6.7 (2020-02-17) - 各种修复

  • 当提供非整数增量时,修正了macOS上的无限滚动。感谢Iván Munsuri Ibáñez

  • 修正了macOS上控制器和监听器对媒体键的处理。感谢Iván Munsuri Ibáñez

v1.6.6 (2020-01-23) - 修正了热键文档

  • 简单的pynput.keyboard.HotKey代码示例现在可以工作。感谢jfongattw

v1.6.5 (2020-01-08) - 修正了媒体键映射

  • 修正了macOS上的媒体键映射。感谢Luis Nachtigall

v1.6.4 (2020-01-03) - 再次修正了导入

  • 修正了键盘控制器中的导入。感谢rhystedstone

v1.6.3 (2019-12-28) - 再次修正了导入

  • 修正了键盘控制器中的导入。感谢Matt Iversen

v1.6.2 (2019-12-28) - 修正了导入

  • 修正了键盘控制器中的导入。感谢Matt Iversen

v1.6.1 (2019-12-27) - Windows的修正

  • 修正了Windows上的全局热键。

  • 修正了Windows上键盘监听器的按下/释放状态。感谢segalion

v1.6.0 (2019-12-11) - 全局热键

  • 添加了对全局热键的支持。

  • 添加了对同步监听事件流的支持。

v1.5.2 (2019-12-06) - 修正了Xorg的媒体键名称

  • 从Xorg键中移除了媒体标志。

v1.5.1 (2019-12-06) - 修正了macOS的媒体键名称

  • 修正了macOS上媒体键的属性名称。感谢ah3243

v1.5.0 (2019-12-04) - 各种改进

  • 修正了Windows上的键盘监听器。感谢akiratakasakisegalionSpecialCharacter

  • 修正了Windows上某些特殊键(包括箭头键)与修饰符组合时的处理。感谢tuessetr

  • 更新文档,包括关于Windows上DPI缩放的说明。感谢david-szarka

  • 添加了对媒体键的实验性支持。感谢ShivamJokerStormTersteeg

v1.4.5(2019-11-05)- 修复了Python 3.8上的错误

  • macOS上的Python 3.8中修复了关于使用in运算符枚举的错误。

v1.4.4(2019-09-24)- 实际上修复了macOS上的键盘监听器

  • 包含提交,以正确回退到CGEventKeyboardGetUnicodeString

  • 修复了关于在Python 3.8中使用Enum的弃用警告。

v1.4.3(2019-09-24)- 再次修复macOS上的键盘监听器

  • 正确回退到CGEventKeyboardGetUnicodeString

  • 更新了文档。

v1.4.2(2019-03-22)- 修复了macOS上的键盘监听器

  • 在macOS键盘监听器中使用CGEventKeyboardGetUnicodeString以发送正确的字符。

  • Xorg键盘监听器中包含键码而不是键码。

  • 修复了日志记录,使其不包括预期的StopException

  • 更新并修复了文档。

v1.4.1(2018-09-07)- 日志记录

  • 记录监听器回调中引发的未处理异常。

v1.4(2018-07-03)- 事件抑制

  • 添加了在监听时完全抑制事件的可能性。

  • 添加了对输入一些控制字符的支持。

  • 添加了对macOS上鼠标拖动事件的支持。感谢jungledrum

  • 在键盘监听器事件中包含键码。

  • Xorg上正确处理了活动num lock下的数字键盘。感谢TheoRet

  • 修复了Windows上当前线程键盘布局的处理。感谢Schmettaling

  • 修复了在Xorg上停止监听器的问题。

  • 修复了在Xorg上导入Xlib.keysymdef.xkb的问题。感谢Glandos

v1.3.10(2018-02-05)- 不要在Xephyr下崩溃

  • Xlib.display.Display.get_input_focus返回整数时,不要崩溃,因为它可能在Xephyr下运行时发生。感谢Eli Skeggs

v1.3.9(2018-01-12)- 正确处理macOS上的字母A

  • 在macOS上生成键盘事件时,修复了虚拟键码的检查。这修复了在按下shift的同时按下A时仍然输入小写字母的问题。

v1.3.8(2017-12-08)- 在某些键盘布局上不要在macOS上崩溃

  • 在macOS上回退到不同的方法来获取键盘布局。这有助于一些键盘布局,如Chinese。感谢haoflynet

v1.3.7(2017-08-23)- Xorg修正

  • 对于Xorg,包括多达30个鼠标按钮。

v1.3.6(2017-08-13)- win32修正

  • 修复了在Windows上双发虚假键盘事件的问题。

  • 修复了在Windows上处理合成Unicode键的问题。

v1.3.5(2017-06-07)- 再次修复依赖关系

  • 撤销了1.3.3中的更改。

  • 修复了Linux上Python 2的平台指定符。

v1.3.4(2017-06-05)- Xorg修正

  • 修复了Xorg上值的边界检查。

v1.3.3(2017-06-05)- 使依赖项非可选

  • 使平台依赖项非可选。

v1.3.2(2017-05-15)- Mac上按钮点击修复

  • 修复了之前版本中按钮点击会导致macos鼠标监听器崩溃的回归问题。

v1.3.1(2017-05-12)- Linux上未知按钮的修复

  • Xorg鼠标监听器中回退到Button.unknown以处理未知鼠标按钮。

v1.3(2017-04-10)- 平台特定功能

  • 添加了在Windows上停止事件传播的能力。这将阻止事件到达其他应用程序。

  • 增加了在Windows上忽略事件的功能。这是针对键盘监控程序干扰正常键盘事件的系统的解决方案。

  • 增加了在OSX上修改事件的功能。这允许在输入事件到达其他应用程序之前拦截和修改它们。

  • 修正了在安装某些类型的第三方输入源时在OSX上崩溃的问题。

v1.2 (2017-01-06) - 改进错误处理

  • 允许捕获来自监听器回调抛出的异常。这改变了API,因为现在加入监听器可能会引发未处理的异常,而未处理的异常将停止监听器。

  • 增加了对Linux上数字小键盘的支持。

  • 改进了文档。

  • 感谢jollyseangilleswijnker提供反馈!

v1.1.7 (2017-01-02) - 处理Windows上的中间按钮

  • 监听并在Windows上分发中间按钮鼠标点击。

v1.1.6 (2016-11-24) - 修正了按键的上下文管理器

  • 修正了pynput.keyboard.Controller.pressed中的错误,该错误导致它永远不会释放按键。多谢Toby Southwell!

v1.1.5 (2016-11-17) - 修正了Linux上的修饰键组合

  • 修正了修饰键的处理,以允许它们在Linux上组合。

v1.1.4 (2016-10-30) - 小型错误修复

  • 修正了当GetKeyboardState失败时生成的错误。

  • 确保将shift状态应用到X上的借用的键。

  • 使用pylint

v1.1.3 (2016-09-27) - 更改Xlib后端库

  • 更改了Xlib库。

v1.1.2 (2016-09-26) - 为Python 2添加缺失的类型

  • Windows上为Python 2添加缺失的LPDWORD

v1.1.1 (2016-09-26) - 修复Windows上的监听器和控制器的问题

  • 修正了Windows上的键盘监听器。现在正确处理了修饰键和其他更改键盘状态的键。

  • 修正了Windows上的鼠标点击和释放。

  • 修正了代码示例。

v1.1 (2016-06-22) - 简化Linux上的使用

  • 将Linux上引发的导入错误传播出去,以帮助调试缺少的Xlib模块。

  • python3-xlib声明为LinuxPython 3的依赖项。

v1.0.6 (2016-04-19) - 通用轮

  • 确保为所有Python版本构建通用轮。

v1.0.5 (2016-04-11) - 修正了OSX上的拖动问题

  • 修正了OSX上的拖动。

  • OSX添加了滚动速度常量以纠正缓慢的滚动速度。

v1.0.4 (2016-04-11) - 修正了Windows上的点击和滚动问题

  • 在发送点击和滚动事件时修正了鼠标输入字段的名称。

v1.0.3 (2016-04-05) - 修正了Windows上的Python 3问题

  • 修正了Windows上的ctypes的使用。

v1.0.2 (2016-04-03) - 修正了线程标识符问题

  • 使用线程标识符来识别线程,而不是Thread实例。

v1.0.1 (2016-04-03) - 修正了Python 3问题

  • 修正了阻止库在Python 3上使用的错误。

v1.0 (2016-02-28) - 稳定版发布

  • 将许可协议更改为LGPL

  • 修正了小错误和不一致之处。

  • 修正并扩展了文档。

v0.6 (2016-02-08) - 键盘监控器

  • 增加了对键盘监控的支持。

  • 修正了轮包装。

  • 在某些情况下,修正了停止监听器时在X上的死锁。

  • 修正了Mac OSX上的键码常量。

  • Mac OSX上不要拦截事件。

v0.5.1 (2016-01-26) - 不要在死键上死亡

  • 修正了死键的处理。

  • 修正了文档。

v0.5 (2016-01-18) - 键盘修饰符

  • 增加了对修饰符的支持。

v0.4 (2015-12-22) - 键盘控制器

  • 增加了键盘控制器。

v0.3 (2015-12-22) - 清理

  • pynput.mouse.Controller.Button 移动到顶层。

v0.2 (2015-10-28) - 首次发布

  • 支持在 LinuxMac OSXWindows 上控制鼠标。

  • 支持在 LinuxMac OSXWindows 上监控鼠标。

项目详情


下载文件

下载适用于您平台的文件。如果您不确定选择哪个,请了解更多关于 安装包 的信息。

源代码分布

pynput-robocorp-fork-5.0.0.tar.gz (76.6 kB 查看哈希值)

上传日期 源代码

构建分布

pynput_robocorp_fork-5.0.0-py3.8.egg (168.5 kB 查看哈希值)

上传日期 源代码

pynput_robocorp_fork-5.0.0-py2.py3-none-any.whl (84.3 kB 查看哈希值)

上传日期 Python 2 Python 3

由以下支持

AWS AWS 云计算和安全赞助商 Datadog Datadog 监控 Fastly Fastly CDN Google Google 下载分析 Microsoft Microsoft PSF 赞助商 Pingdom Pingdom 监控 Sentry Sentry 错误记录 StatusPage StatusPage 状态页面