Код клавиши в Python: как получить и использовать
Получение кода клавиши в Python: обработка ввода в GUI
Как получить код нажатой клавиши (скан-код или символ) в приложении на tkinter?
Наиболее эффективным способом для стандартных GUI-приложений является использование модуля tkinter и метода bind(). Событие клавиши содержит атрибуты char (символ) и keycode (целочисленный код клавиши).
Пример простого окна, которое выводит код клавиши и символ при каждом нажатии:
import tkinter as tk
def on_key(event):
print(f'Символ: {event.char} | Код: {event.keycode}')
root = tk.Tk()
root.bind('', on_key)
root.mainloop() код клавиши python (код клавиши в python)
При нажатии, к примеру, на 'A' в консоли появится:
Символ: a | Код: 65
Пояснение: event.char даёт строку с одним символом (если клавиша печатающая, иначе пустую строку). event.keycode выдаёт число, которое может отличаться в разных операционных системах (например, для стрелок в Windows это 37-40). Для обработки специальных клавиш (F1, Shift, Ctrl) удобно использовать event.keysym (текстовое имя).
Проблемы и типичные ошибки:
- Клавиши-модификаторы (Shift, Ctrl) не генерируют событие
при отдельном нажатии – необходимо использовать и проверять event.keysym. - В Linux keycode может быть 0 для некоторых событий (например, для 'a' – 38, но это зависит от дистрибутива).
- Не путать event.char и event.keysym – char содержит символ после обработки модификаторов, keysym – имя клавиши ('a', 'A', 'Shift_L').
Решение: всегда проверять event.keysym для специальных клавиш, а для текстового ввода использовать event.char с проверкой длины.
Как перехватывать клавиши глобально (вне окна) с помощью модуля keyboard?
Если требуется обрабатывать нажатия в любом приложении системы, подходит сторонняя библиотека keyboard. Она даёт доступ к скан-кодам и символам, а также позволяет вешать хуки.
import keyboard
def on_key(event):
print(f'Клавиша: {event.name} | Скан-код: {event.scan_code}')
keyboard.on_press(on_key)
keyboard.wait('esc') # выход по Esc
Клавиша: a | Скан-код: 30 Клавиша: enter | Скан-код: 28
Пояснение: event.name содержит название клавиши, event.scan_code – скан-код (аппаратный код). Важно: требуется запускать скрипт с правами администратора (на Linux – sudo).
Ошибки: импорт keyboard может не установиться, требуется pip install keyboard. На macOS и Linux работа может быть ограничена.
Как получить код клавиши в игровых приложениях на Pygame?
В библиотеке pygame события клавиш содержат атрибут key – целочисленный код клавиши (константа из pygame.locals).
import pygame
pygame.init()
screen = pygame.display.set_mode((400, 300))
clock = pygame.time.Clock()
running = True
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
elif event.type == pygame.KEYDOWN:
print(f'Код клавиши: {event.key}')
clock.tick(30)
pygame.quit()
Код клавиши: 97 (для 'a') Код клавиши: 1073741906 (для стрелки влево)
Пояснение: event.key выдаёт константу, например pygame.K_a равен 97. Для специальных клавиш удобно сравнивать с константами: if event.key == pygame.K_ESCAPE.
Проблемы: если не импортировать pygame.locals, константы могут быть недоступны. Код клавиши может быть отрицательным на некоторых платформах?
Как получить ASCII-код нажатой клавиши в консоли (curses)?
Для терминальных приложений на Linux/macOS можно использовать curses. Функция getch() возвращает целочисленный ASCII-код (или код специальной клавиши).
import curses
def main(stdscr):
stdscr.addstr('Нажмите любую клавишу...')
key = stdscr.getch()
stdscr.addstr(f'\nКод клавиши: {key}')
stdscr.refresh()
stdscr.getch()
curses.wrapper(main)
Нажмите любую клавишу... Код клавиши: 97 (для 'a')
Пояснение: curses.wrapper инициализирует экран. getch() возвращает код символа или константу (например, curses.KEY_LEFT – 260).
Ошибки: curses не работает на Windows из коробки; нужно устанавливать дополнительную библиотеку (windows-curses).
Как просто считать символ в консоли Windows (без ожидания Enter)?
На Windows есть функция msvcrt.getch() из модуля msvcrt. Она возвращает байт (или два байта для специальных клавиш).
import msvcrt
print('Нажмите клавишу...')
key = msvcrt.getch()
print(f'ASCII-код: {ord(key) if len(key) == 1 else key[0]}')
Нажмите клавишу... ASCII-код: 97
Пояснение: getch() возвращает bytes длины 1 или 2 (для функциональных клавиш). Для преобразования в int используем ord().
Проблемы: работает только в командной строке Windows. Для стрелок нужно обрабатывать два байта.
Как получить код клавиши через pynput?
Библиотека pynput – кроссплатформенное решение для глобального перехвата. Предоставляет информацию о коде клавиши.
from pynput import keyboard
def on_press(key):
try:
print(f'Альфа-клавиша: {key.char} с кодом {key.vk}')
except AttributeError:
print(f'Специальная клавиша: {key.name} с кодом {key.value.vk}')
with keyboard.Listener(on_press=on_press) as listener:
listener.join()
Примечание: key.vk – виртуальный код клавиши (может меняться в разных ОС). Для специальных клавиш атрибут char отсутствует.
Ошибки: на macOS и Linux может потребоваться разрешение на доступ к устройствам ввода.
Дополнительные примеры использования кода клавиши
Пример 1. Запись лога нажатий с временными метками (tkinter + csv)
import tkinter as tk
import csv
from datetime import datetime
def on_key(event):
data = {
'time': datetime.now().isoformat(),
'char': event.char,
'keycode': event.keycode,
'keysym': event.keysym
}
with open('keylog.csv', 'a', newline='') as f:
writer = csv.DictWriter(f, fieldnames=data.keys())
writer.writerow(data)
root = tk.Tk()
root.bind('', on_key)
root.title('Логгер нажатий (демонстрация)')
root.geometry('300x200')
root.mainloop()
(после нажатия клавиш в файле keylog.csv появятся записи)
Пример 2. Обработка комбинаций клавиш (Ctrl+C) в tkinter
import tkinter as tk
def copy(event):
print('Копирование: Ctrl+C')
root = tk.Tk()
root.bind('', copy)
root.mainloop()
Копирование: Ctrl+C
Пример 3. Определение кода клавиши для стрелок в Pygame и выполнение действий
import pygame
pygame.init()
screen = pygame.display.set_mode((400, 300))
clock = pygame.time.Clock()
x, y = 200, 150
running = True
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
elif event.type == pygame.KEYDOWN:
if event.key == pygame.K_LEFT:
x -= 10
elif event.key == pygame.K_RIGHT:
x += 10
elif event.key == pygame.K_UP:
y -= 10
elif event.key == pygame.K_DOWN:
y += 10
print(f'Клавиша: {event.key}, позиция: ({x},{y})')
screen.fill((0,0,0))
pygame.draw.circle(screen, (255,255,255), (x, y), 10)
pygame.display.flip()
clock.tick(30)
pygame.quit()
Клавиша: 276, позиция: (190,150) (после нажатия влево)
Пример 4. Получение скан-кода клавиши через модуль keyboard с фильтрацией
import keyboard
def printer(event):
if event.scan_code == 30: # скан-код 'a'
print('Нажата клавиша A (скан-код 30)')
keyboard.hook(printer)
keyboard.wait('esc')
Нажата клавиша A (скан-код 30)
Пример 5. Использование pynput для отслеживания нажатия мыши и клавиш одновременно
from pynput import keyboard, mouse
def on_press(key):
try:
print(f'Клавиша {key.char} (vk={key.vk})')
except AttributeError:
print(f'Специальная {key.name} (vk={key.value.vk})')
def on_click(x, y, button, pressed):
if pressed:
print(f'Мышь {button} на координатах ({x}, {y})')
with keyboard.Listener(on_press=on_press) as kl, mouse.Listener(on_click=on_click) as ml:
kl.join()
ml.join()
Клавиша a (vk=65) Специальная shift (vk=16) Мышь Button.left на координатах (500, 300)