Как получить коды ключей в Python
Вопрос
Мне нужно знать, какая клавиша нажата, но не нужен код символа, я хочу знать, когда кто-то нажимает клавишу "A", даже если полученная клавиша "a" или "A", и так со всеми другими клавишами.
Я не могу использовать PyGame или любую другую библиотеку (включая Tkinter).Только стандартная библиотека Python.И это должно быть сделано в терминале, а не в графическом интерфейсе.
НЕ НУЖЕН СИМВОЛЬНЫЙ КОД.Мне НУЖНО ЗНАТЬ КОД КЛЮЧА.
Бывший:
ord('a') != ord('A') # 97 != 65
someFunction('a') == someFunction('A') # a_code == A_code
Решение
Видишь tty стандартный модуль.Это позволяет переключаться из режима, ориентированного на строки по умолчанию (приготовленный), в режим, ориентированный на символы (cbreak), с tty.setcbreak(системный стандарт).Чтение одного символа из sys.stdin приведет к следующему нажатию клавиши клавиатуры (если она генерирует код):
import sys
import tty
tty.setcbreak(sys.stdin)
while True:
print ord(sys.stdin.read(1))
Примечание:решение предназначено только для Unix (включая Linux).
Редактировать:В Windows попробуйте msvcrt.getche()/getwche()./мне негде пробовать...
Правка 2:Используйте низкоуровневый консольный API win32 через типы.windll (см. пример в SO) с ReadConsoleInput
функция.Вы должны отфильтровывать нажатия клавиш - e.EventType==KEY_EVENT
и искать e.Event.KeyEvent.wVirtualKeyCode
ценность.Пример приложения (не на Python, просто чтобы получить представление) можно найти по адресу http://www.benryves.com/tutorials/?t=winconsole&c=4.
Другие советы
В зависимости от того, чего вы пытаетесь достичь, возможно, используя библиотеку, такую как пигмея сделал бы то, что ты хочешь.Pygame содержит более продвинутую обработку нажатий клавиш, чем обычно доступно в стандартных библиотеках Python.
Вероятно, вам придется использовать Ткинтеръ, который является "стандартным" графическим интерфейсом Python и был включен в python в течение многих лет.
Решение из командной строки, вероятно, недоступно из-за способа передачи данных в процессы командной строки и из них.Все программы с графическим интерфейсом (того или иного типа) получают пользовательский ввод через поток событий (возможно, завернутый в библиотеку).Каждое событие будет представлять собой запись подробностей о событии.Для событий нажатия клавиши запись может содержать любой код ключа, битовое поле ключа-модификатора или текстовый символ в некоторой кодировке.Какие поля и как они называются, зависит от библиотеки событий, которую вы вызываете.
Программы командной строки получают пользовательский ввод через потоки символов.Нет никакого способа перехватить данные более низкого уровня.Как объяснил Мирослав в своем посте, tty могут быть в приготовленном или сыром режиме, с той лишь разницей, что в приготовленном режиме терминал будет обрабатывать (некоторые) управляющие символы для вас, такие как delete и enter, чтобы процесс получал строки ввода вместо 1 символа за раз.
Обработка чего-либо ниже этого уровня требует (зависит от операционной системы) системных вызовов или открытия символьных устройств в / dev.Стандартная библиотека Python не предоставляет стандартных средств для этого.
Если вам нужно работать только в Windows, вы должны попробовать msvcrt.
Очевидный ответ:
someFunction = string.upper
ord('a') != ord('A') # 97 != 65
someFunction('a') == someFunction('A') # a_code == A_code
или, другими (ключевыми)словами:
char_from_user = getch().upper() # read a char converting to uppercase
if char == 'Q':
# quit
exit = True # or something
elif char in ['A', 'K']:
do_something()
и т.д...
Вот реализация функции getch, которая будет работать как на платформах Windows, так и на Linux, на основе этого рецепта:
class _Getch(object):
"""Gets a single character from standard input.
Does not echo to the screen."""
def __init__(self):
try:
self.impl = _GetchWindows()
except ImportError:
self.impl = _GetchUnix()
def __call__(self):
return self.impl()
class _GetchUnix(object):
def __init__(self):
import tty, sys
def __call__(self):
import sys, tty, termios
fd = sys.stdin.fileno()
old_settings = termios.tcgetattr(fd)
try:
tty.setraw(sys.stdin.fileno())
ch = sys.stdin.read(1)
finally:
termios.tcsetattr(fd, termios.TCSADRAIN, old_settings)
return ch
class _GetchWindows(object):
def __init__(self):
import msvcrt
def __call__(self):
import msvcrt
return msvcrt.getch()
getch = _Getch()
эта функция вернет код для символа верхнего регистра:
def upCcode( ch ):
if(len(ch) == 1):
return ord(ch.upper())
и это для символьного кода в нижнем регистре:
def lowCcode( ch ):
if(len(ch) == 1):
return ord(ch.lower())
этот способ намного проще, и вам не нужно будет импортировать внешние библиотеки.
Вам нужно будет выбрать один из двух методов, который будет "someFunction", который вы описали в своем вопросе.Вот пример:
ВЫХОДНОЙ СИГНАЛ:
# when using upCode():
>> upCcode('a')
65
>> upCcode('A')
65
# when using lowCode():
>> lowCcode('a')
97
>> lowCcode('A')
97
Взгляните на пинпут модуль на Python.Он также имеет приятный Учебник используя который, вы можете легко создавать прослушиватели клавиатуры для вашего кода.
Официальным примером для слушателей является:
from pynput.keyboard import Key, Listener
def on_press(key):
print('{0} pressed'.format(
key))
def on_release(key):
print('{0} release'.format(
key))
if key == Key.esc:
# Stop listener
return False
# Collect events until released
with Listener(on_press=on_press,
on_release=on_release) as listener:
listener.join()
Надеюсь, это поможет.