Код клавиши в Python: как получить и использовать

Раздел: GUI -> Обработка ввода

Получение кода клавиши в 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)

Код клавиши в Python - comments

En
код клавиши python (python)