Мониторинг и управление клавиатурой в Python
Использование модуля pynput.keyboard библиотеки pynput в Python
Модуль pynput.keyboard библиотеки pynput содержит классы для управления и мониторинга клавиатуры.
Содержание:
- Управление клавиатурой;
- Мониторинг клавиатуры;
- Поток слушателя клавиатуры Listener ;
- Обработка ошибок слушателя клавиатуры;
- Переключение прослушивания событий для клавиатуры;
- Синхронное прослушивание событий для клавиатуры;
- Прослушивание глобальных горячих клавиш;
Управление клавиатурой.
Для управления клавиатурой используйте класс keyboard.Controller следующим образом:
from pynput.keyboard import Key, Controller keyboard = Controller() # Нажимает и отпускает клавишу пробела keyboard.press(Key.space) keyboard.release(Key.space) # печатает строчную букву `a`, будет работать, даже если ни # одна клавиша на физической клавиатуре не помечена буквой `a`. keyboard.press('a') keyboard.release('a') # печатает две заглавные буквы `A`: # выводим сразу заглавную 'A' keyboard.press('A') keyboard.release('A') # выводим заглавную 'A' через нажатие `Key.shift` with keyboard.pressed(Key.shift): keyboard.press('a') keyboard.release('a') # печатает 'Hello World', используя метод быстрого ввода keyboard.type('Hello World')
Мониторинг клавиатуры.
Для мониторинга клавиатуры используйте класс keyboard.Listener следующим образом:
from pynput import keyboard def on_press(key): try: print(f'Нажата буквенно-цифровая клавиша: key.char>') except AttributeError: print(f'Нажата специальная клавиша: key>') def on_release(key): print(f'key> released') if key == keyboard.Key.esc: # Возврат False - остановит слушатель return False # блок `with` слушает события до выхода # до остановки слушателя with keyboard.Listener( on_press=on_press, on_release=on_release) as listener: listener.join() #. или неблокирующим способом: listener = keyboard.Listener( on_press=on_press, on_release=on_release) listener.start()
Слушатель клавиатуры keyboard.Listener — это threading.Thread , и все обратные вызовы будут вызываться из потока.
Чтобы остановить слушатель клавиатуры, можно вызвать keyboard.Listener.stop() из любого места, что в свою очередь вызовет исключение StopException или возвратить False из функции обратного вызова.
Аргумент key , который передается слушателем в обратные вызовы, является keyboard.Key для специальных клавиш и keyboard.KeyCode для обычных буквенно-цифровых клавиш или просто None для неизвестных клавиш.
При использовании приведенной выше неблокирующей версии текущий поток продолжит выполнение. Это может быть необходимо при интеграции с другими платформами графического интерфейса, включающими основной цикл, но при запуске из скрипта это приведет к немедленному завершению программы.
Поток слушателя клавиатуры keyboard.Listener .
Обратные вызовы слушателя keyboard.Listener , на некоторых платформах, особенно в Windows, вызываются непосредственно из рабочего потока. Это означает, что длительно выполняющиеся процедуры и блокирующие операции не должны вызываться из обратного вызова, так как это может привести к зависанию ввода для всех процессов.
Возможный обходной путь — это просто отправить входящие события в очередь и позволить отдельному потоку обрабатывать их.
Обработка ошибок слушателя клавиатуры.
Если обработчик обратного вызова вызывает исключение, то слушатель будет остановлен. Поскольку обратные вызовы выполняются в выделенном потоке, исключения не будут автоматически повторно вызываться.
Чтобы получать уведомления об ошибках обратного вызова, необходимо вызвать Thread.join() для экземпляра слушателя keyboard.Listener :
from pynput import keyboard class MyException(Exception): pass def on_press(key): if key == keyboard.Key.esc: raise MyException(key) # блок `with` слушает события до выхода with keyboard.Listener( on_press=on_press) as listener: try: listener.join() except MyException as e: print(f'e.args[0]>')
Переключение прослушивания событий для клавиатуры.
После вызова keyboard.Listener.stop() слушатель не может быть перезапущен, так как слушатели keyboard.Listener являются экземплярами threading.Thread .
Если приложение требует переключения событий keyboard.Listener , то необходимо либо добавить внутренний флаг для игнорирования событий, когда они не требуются, либо создать новый слушатель keyboard.Listener для возобновления прослушивания.
Синхронное прослушивание событий для клавиатуры.
Для упрощения написания сценариев с синхронным прослушиванием событий поддерживается служебный класс keyboard.Events . Этот класс поддерживает чтение отдельных событий неблокирующим способом, а также повторение всех событий.
Чтобы прочитать одно событие, используйте следующий код:
from pynput import keyboard # В блоке `with` будет работать слушатель событий. with keyboard.Events() as events: # Блокировать не более одной секунды event = events.get(1.0) if event is None: print('Вы не нажали клавишу в течение одной секунды') else: print('Получено событие ')
Чтобы перебрать события клавиатуры, используйте следующий код:
from pynput import keyboard # В блоке `with` будет работать слушатель событий. with keyboard.Events() as events: for event in events: if event.key == keyboard.Key.esc: # выход из слушателя break else: print('Получено событие ')
Обратите внимание, что контекстный менеджер with не поддерживает неблокирующую операцию, поэтому он будет ожидать хотя бы одно событие клавиатуры.
События будут экземплярами внутренних классов, найденных в keyboard.Events .
Прослушивание глобальных горячих клавиш.
Обычный вариант использования клавиатурных мониторов — реакция на глобальные горячие клавиши. Так как слушатель не поддерживает никакого состояния, то горячие клавиши, использующие сочетания несколько клавиш, должны где-то хранить это состояние.
Для этой цели модуль pynput предоставляет класс keyboard.HotKey . Он содержит два метода для обновления состояния, предназначенных для простого взаимодействия со слушателем клавиатуры: keyboard.HotKey.press и keyboard.HotKey.release , которые можно напрямую передавать в качестве обратных вызовов слушателя.
Предполагаемое использование выглядит следующим образом:
from pynput import keyboard def on_activate(): print('Активирована глобальная горячая клавиша!') def for_canonical(f): return lambda k: f(l.canonical(k)) # определение горячей клавиши hotkey = keyboard.HotKey( keyboard.HotKey.parse('++h'), on_activate) with keyboard.Listener( on_press=for_canonical(hotkey.press), on_release=for_canonical(hotkey.release)) as l: l.join()
Представленный код создаст горячую клавишу, а затем использует слушатель для обновления ее состояния. Как только все указанные клавиши одновременно будут нажаты, будет вызвана функция on_activate() .
Обратите внимание, что ключи передаются через keyboard.Listener.canonical перед передачей экземпляру keyboard.HotKey . Это делается для того, чтобы удалить любое состояние модификатора из ключевых событий и нормализовать модификаторы с более чем одной физической клавишей.
Метод keyboard.HotKey.parse — это удобная функция для преобразования строк быстрого доступа в наборы ключей. для получения дополнительной информации, смотрите его документацию keyboard.HotKey .
Чтобы зарегистрировать несколько глобальных горячих клавиш, используйте вспомогательный класс keyboard.GlobalHotKeys :
from pynput import keyboard def on_activate_h(): print('Нажато сочетание клавиш: ++h') def on_activate_i(): print('Нажато сочетание клавиш: ++i') with keyboard.GlobalHotKeys( '++h': on_activate_h, '++i': on_activate_i>) as h: h.join()
- КРАТКИЙ ОБЗОР МАТЕРИАЛА.
- Мониторинг и управление клавиатурой
- Мониторинг за состоянием и управление мышью
- Класс keyboard.Controller() модуля pynput
- Класс keyboard.Listener() модуля pynput
- Класс keyboard.Key модуля pynput
- Класс keyboard.KeyCode() модуля pynput
- Класс mouse.Controller() модуля pynput
- Класс mouse.Listener() модуля pynput
Как научить Python использовать клавиатуру и мышь. Часть 1

В любой работе рано или поздно наступает момент, когда на компьютере нужно выполнять монотонные задачи, повторяя одни и те же действия из раза в раз. Кажется, что это можно было бы легко автоматизировать, ведь алгоритм прост и понятен, но на практике оказывается, что подходящий инструмент для такой автоматизации найти трудно. Но это не значит, что такой инструмент нельзя создать.
Цель: написать программу на языке Python для создания простых макросов, сначала записывающих, а после воспроизводящих действия клавиатуры и мыши. Управление программой будет происходить через графический интерфейс.
В начале потребуется библиотека для записи действий мыши и клавиатуры. В качестве таковой возьмём pynput.
Для отслеживания действий клавиатуры нужно инициализировать класс Listener. В качестве аргументов он принимает две функции: первая активируется, когда пользователь нажимает клавишу, а вторая – когда отпускает. Задействованные клавиши передаются этим функциям в аргументе. Далее нужно запустить саму прослушку клавиатуры. Всё это выглядит следующем образом:
from pynput import keyboard # Действие, когда пользователь нажимает клавишу на клавиатуре def on_press(key): print(f'Была нажата клавиша ') # Действие, когда пользователь отпускает клавишу на клавиатуре def on_release(key): print(f'Была отпущена клавиша ') # Инициализация прослушки клавиатуры keyboard_listener = keyboard.Listener( on_press=on_press, on_release=on_release ) # Старт прослушки клавиатуры keyboard_listener.start() # Здесь может выполняться другой код # Остановка прослушки клавиатуры keyboard_listener.stop()
Для прослушки мыши нужно выполнить похожие действия, отличие лишь в том, что Listener для мыши принимает три функции: для перемещения курсора, для нажатия клавиши мыши и для пролистывания. Единица координат курсора – пиксель, отсчет системы координат ведётся от левого верхнего угла монитора.
from pynput import mouse # Действие при движении курсора def on_move(x, y): print(f'Курсор переместился на позицию ' f' по горизонтали и по вертикали') # Действие при нажатии кнопки мыши def on_click(x, y, button, is_pressed): print(f'Была ' f'клавиша на позиции ' f' по горизонтали и по вертикали') # Действие при прокручивании def on_scroll(x, y, dx, dy): horizontal_scroll = '' if dx < 0: horizontal_scroll = 'влево' elif dx >0: horizontal_scroll = 'вправо' vertical_scroll = '' if dy < 0: vertical_scroll = 'вниз' elif dy >0: vertical_scroll = 'вверх' print(f'Была прокрутка ' f' на позиции ' f' по горизонтали и по вертикали') # Прослушка мыши mouse_listener = mouse.Listener( on_move=on_move, on_click=on_click, on_scroll=on_scroll ) # Старт прослушки мыши mouse_listener.start() # Здесь может выполняться другой код # Остановка прослушки мыши mouse_listener.stop()
Чтобы иметь возможность воспроизвести действия пользователя, прослушку клавиатуры и мыши нужно куда-то сохранить. Удобнее всего каждое действие записывать в словарь, где указывать устройство и что нажал пользователь. Все эти словари помещаем в список, который соответствует последовательности ввода.
Исходя из этого, получается следующая функция:
# Последовательность действий клавиатуры и мыши track = [] # Добавление новых действий клавиатуры и мыши # device - название контроллера ('keyboard', 'mouse') # action - действие ('press', 'release', 'move', 'scroll') # kwargs - все остальные параметры def add_action(device, action, **kwargs): if action not in ['press', 'release', 'move', 'scroll']: raise ValueError('Wrong action name.') if device == 'keyboard': # Если был ввод с клавиатуры, то просто перечисляем параметры track.append(< 'device': device, 'action': action, 'key': kwargs['key'] >) elif device == 'mouse': # Если был ввод с мыши, то сначала указываем положение курсора action_dict = < 'device': device, 'action': action, 'x': kwargs['x'], 'y': kwargs['y'] ># а после добавляем дополнительные параметры # в зависимости от действия if action == 'press' or action == 'release': action_dict['key'] = kwargs['key'] if action == 'scroll': action_dict['dx'] = kwargs['dx'] action_dict['dy'] = kwargs['dy'] self.track.append(action_dict)
А чтобы имитировать действия клавиатуры или мыши нужно использовать класс Controller из той же библиотеки pynput. Если исходить из того способа записи прослушки, что описан чуть выше, то функция для имитации будет иметь следующий вид:
from pynput import keyboard, mouse def run(): keyboard_controller = keyboard.Controller() mouse_controller = mouse.Controller() for t in self.track: time.sleep(0.1) # Действия клавиатуры if t['device'] == 'keyboard': # Нажатие клавиши клавиатуры if t['action'] == 'press': keyboard_controller.press(t['key']) # Отпуск клавиши клавиатуры elif t['action'] == 'release': keyboard_controller.release(t['key']) # Действия мыши if t['device'] == 'mouse': # Движение мыши mouse_controller.move( t['x'] - mouse_controller.position[0], t['y'] - mouse_controller.position[1] ) # Прокручивание колёсика if t['action'] == 'scroll': mouse_controller.scroll(t['dx'], t['dy']) # Нажатие кнопки мыши elif t['action'] == 'press': mouse_controller.press(t['key']) # Отпуск кнопки мыши elif t['action'] == 'release': mouse_controller.release(t['key'])
Чтобы не переполнять текст вставками кода, полная версия с использованием библиотеки pynput для прослушки и имитации клавиатуры или мыши расположена в репозитории github, ссылка на который находится в конце поста.
Единственное, что стоит отметить – это остановка прослушки при нажатии на правый shift. Клавишу можно выбрать любую, но так как правый shift используется реже, то удобнее использовать его. В коде это выглядит так:
def on_press(key): if key == keyboard.Key.shift_r: keyboard_listener.stop() mouse_listener.stop() return .
Теперь, для удобства восприятия, будет создан простой интерфейс с использованием библиотеки PySimpleGUI. В этом интерфейсе будут отображаться записанные действия пользователя, а также кнопки для старта записи или запуска имитации. Чтобы создать окно, с которым можно взаимодействовать, нужно инициализировать класс Window, передав в него двумерный список layout, представляющий собой взаимное расположение элементов:
import PySimpleGUI as psg # Элементы интерфейса layout = [ # Клавиши для изменения последовательности записанных действий [psg.Button('Up'), psg.Button('Down')], # Дерево для отображения самих записанных действий [psg.Tree(data=psg.TreeData(), key='Keys tree', headings=[])], # Кнопки для управления записью [psg.Button('Run'), psg.Button('Record')] ] # Создание окна wnd = psg.Window('Holop', layout, size=(500, 500))
Перехват нажатий осуществляется в бесконечном цикле, выйти из которого можно только тогда, когда пользователь закроет окно интерфейса:
while True: # Ожидание события окна event, values = wnd.read() # Выбор действия в зависимости от нажатой кнопки if event == psg.WINDOW_CLOSED: # Выход break elif event == 'Up': # Поднять выбранные элементы replace_elem(wnd.Element('Keys tree'), 'up') elif event == 'Down': # Опустить выбранные элементы replace_elem(wnd.Element('Keys tree'), 'down') elif event == 'Run': # Запустить имитацию действий клавиатуры и мыши run() elif event == 'Record': # Запустить прослушку клавиатуры и мыши start_record() wnd.close()
Как производится запись и имитация действий клавиатуры и мыши рассказано выше, а вот для перемещения элементов используется следующий код:
# Поднимает или опускает выбранные элементы def replace_elem(tree, direction): # Список выбранных элементов select_elems = tree.Widget.selection() # Если ни один элемент не выбран, то выход if len(select_elems) == 0: return # Получение основных элементов дерева treedata = tree.TreeData tree_root = treedata.tree_dict[''] # Перемещение всех выбранных элементов for s_e in select_elems: # Получение отмеченного элемента elem = treedata.tree_dict[tree.IdToKey[s_e]] ind = tree_root.children.index(elem) # Перемещение этого элемента if direction == 'up' and ind >= 0: tree_root.children[ind-1], tree_root.children[ind] =\ tree_root.children[ind], tree_root.children[ind-1] track[ind-1], track[ind] = track[ind], track[ind-1] elif direction == 'down' and ind < len(tree_root.children): tree_root.children[ind], tree_root.children[ind+1] =\ tree_root.children[ind+1], tree_root.children[ind] track[ind], track[ind+1] = track[ind+1], track[ind] # Обновление дерева tree.update(values=treedata)
После запуска кода перед нами появляется окно, с которым можно взаимодействовать:

В итоге получаем программу, которая может запоминать и воспроизводить действия клавиатуры и мыши, имеет простой интерфейс, чтобы ориентироваться в этих записях.
Здесь были разобраны основные компоненты программы, её полная версия с дополнительным функционалом размещена по ссылке ниже. Воспользоваться ей можно, например, при заполнении множества типовых форм, копируя данные из файла excel, или при установке программ на разных компьютерах через их графический интерфейс, когда скриптом это сделать нельзя.
Установил модуль "keyboard", а python его не видит [закрыт]
Вопрос вызван проблемой, которая больше не воспроизводится, или опечаткой. Хотя похожие вопросы могут быть уместны на этом сайте, решение для этого вопроса вряд ли поможет будущим посетителям. Обычно можно избежать подобных вопросов написанием и исследованием минимальной программы для воспроизведения проблемы до публикации вопроса.
Закрыт 2 года назад .
Я установил модуль "keyboard", а Python его не видит. Импортировал модуль я так:
from keyboard import is_pressed, write, send
Но как бы я не старался переустанавливать модуль стандартный IDLE его не видит, как это можно исправить? Проблема скорее всего появилась когда я устанавливал новую версию Python Мои попытки установки и переустановки:
Дополнение: Только-что попробовал запустить Python файл через cmd и каким-то чудом он не стал жаловаться на отсутствие библиотеки и просто заработал. Всё-таки я хочу разобраться почему так происходит. Помогите пожалуйста!
Отслеживать
11.8k 2 2 золотых знака 10 10 серебряных знаков 28 28 бронзовых знаков
задан 13 янв 2021 в 1:35
49 5 5 бронзовых знаков
У Вас стоит две разных версии python? Попробуйте просто запустить python из cmd (просто интерпретатор, не передавая ему файл скрипта), какую версию напишет?
13 янв 2021 в 2:15
Посмотрите данный вопрос. Возможно pip установил пакет на python2 . Как написано в предыдущем комментарии. проверьте вашу версию python . Пропробуйте pip3 install keyboard для установки на python3
13 янв 2021 в 5:50
@V-Mor Версия Python у меня Python 3.9.1 (i.imgur.com/kiBbUsn.png) @Sherlock У меня никогда небыл установлен любой Python 2.x, установка 100% была сделана на Python 3.9.1, так же я уже пробовал ранее устанавливать библиотеку при помощи команды pip3
14 янв 2021 в 20:50
Возможно, глупый вопрос, но Вы перезапускали IDLE после установки модуля? А то мало ли.
15 янв 2021 в 1:25
@V-Mor Да, я перезагружал IDLE, действительно странный вопрос) Я так-же неоднократно перезагружал полностью систему.
15 янв 2021 в 10:46
1 ответ 1
Сортировка: Сброс на вариант по умолчанию
1 вариант решения: Чтобы Python увидел библиотеку запускать скрипт нужно через командную строку (cmd). Не знаю как так происходило, но оно так работало.
2 вариант решения: Так-же работает вариант переустановить систему и последующая установка чистейшего Python на новую систему, тогда внутри системы Python перестанет конфликтовать сам с собой или с системой. Незнаю как так получилось, но это скорее всего конфликт Python с чем-то что мне не ведомо)
Мне помогло лишь переустановить полностью систему, тем самым конфликты системы с Python видимо исчезли и он стал нормально воспринимать установленную мной библиотеку "keyboard" [Ранее я уже пробовал переустанавливать Python или откатываться назад на предыдущие версии (может там что-то бы заработало), но нечего не помогало, лишь переустановка системы (Что достаточно радикально!), помогло мне справиться с проблемой.]
Это одиночная ошибка которую я допустил я сам и из-за этого скорее всего подобных случаев не будет происходить с другими людьми, было неправильно задавать такой вопрос здесь)
keyboard
Take full control of your keyboard with this small Python library. Hook global events, register hotkeys, simulate key presses and much more.
Features
- Global event hook on all keyboards (captures keys regardless of focus).
- Listen and send keyboard events.
- Works with Windows and Linux (requires sudo), with experimental OS X support (thanks @glitchassassin!).
- Pure Python, no C modules to be compiled.
- Zero dependencies. Trivial to install and deploy, just copy the files.
- Python 2 and 3.
- Complex hotkey support (e.g. ctrl+shift+m, ctrl+space ) with controllable timeout.
- Includes high level API (e.g. record and play, add_abbreviation).
- Maps keys as they actually are in your layout, with full internationalization support (e.g. Ctrl+ç ).
- Events automatically captured in separate thread, doesn't block main program.
- Tested and documented.
- Doesn't break accented dead keys (I'm looking at you, pyHook).
- Mouse support available via project mouse ( pip install mouse ).
Usage
pip install keyboard
or clone the repository (no installation required, source files are sufficient):
git clone https://github.com/boppreh/keyboard
or download and extract the zip into your project folder.
Then check the API docs below to see what features are available.
Example
- Events generated under Windows don't report device id ( event.device == None ). #21
- Media keys on Linux may appear nameless (scan-code only) or not at all. #20
- Key suppression/blocking only available on Windows. #22
- To avoid depending on X, the Linux parts reads raw device files ( /dev/input/input* ) but this requires root.
- Other applications, such as some games, may register hooks that swallow all key events. In this case keyboard will be unable to report events.
- This program makes no attempt to hide itself, so don't use it for keyloggers or online gaming bots. Be responsible.