Как получить коды клавиш в Python - PullRequest
7 голосов
/ 22 февраля 2009

Мне нужно знать, какая клавиша нажата, но мне не нужен код символа, я хочу знать, когда кто-то нажимает клавишу «А», даже если полученная клавиша «А» или «А», и поэтому все остальные ключи.

Я не могу использовать PyGame или любую другую библиотеку (включая Tkinter). Только стандартная библиотека Python. И это должно быть сделано в терминале, а не в графическом интерфейсе.

НЕ НУЖЕН КОД ХАРАКТЕРА. Я ДОЛЖЕН ЗНАТЬ КЛЮЧЕВОЙ КОД.

Ex:

ord('a') != ord('A')                      # 97 != 65
someFunction('a') == someFunction('A')    # a_code == A_code

Ответы [ 7 ]

20 голосов
/ 23 февраля 2009

См. tty стандартный модуль. Он позволяет переключаться из линейного (готового) режима по умолчанию в режим с символами (cbreak) с помощью tty.setcbreak (sys.stdin) . Чтение одного символа из 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 через ctypes.windll (см. Пример в SO ) с функцией ReadConsoleInput. Вы должны отфильтровать нажатия клавиш - e.EventType==KEY_EVENT и искать значение e.Event.KeyEvent.wVirtualKeyCode. Пример приложения (не на Python, просто чтобы получить представление) можно найти по адресу http://www.benryves.com/tutorials/?t=winconsole&c=4.

9 голосов
/ 22 февраля 2009

В зависимости от того, что вы пытаетесь достичь, возможно, использование библиотеки, такой как pygame , будет делать то, что вы хотите. Pygame содержит более сложную обработку нажатий клавиш, чем обычно доступно в стандартных библиотеках Python.

3 голосов
/ 22 февраля 2009

Вам, вероятно, придется использовать Tkinter , который является «стандартным» графическим интерфейсом Python и входит в состав Python уже много лет.

Решение для командной строки, вероятно, недоступно из-за способа передачи данных в процессы командной строки и из них. Все программы с графическим интерфейсом (того или иного вида) получают пользовательский ввод через поток событий (возможно, в виде библиотеки). Каждое событие будет записывать детали события. Для событий нажатия клавиши запись может содержать любой код клавиши, битовое поле ключа модификации или текстовый символ в некоторой кодировке. Какие поля и как они называются, зависят от библиотеки событий, которую вы вызываете.

Программы командной строки получают пользовательский ввод через символьные потоки. Нет способа поймать данные более низкого уровня. Как пояснил Мирослав в своем посте, tty может быть в режиме «приготовлено» или «не готово», единственное отличие состоит в том, что в режиме «приготовлено» терминал будет обрабатывать (некоторые) управляющие символы для вас, такие как удаление и ввод, так что процесс получит строки ввода вместо по 1 персонажу за раз.

Обработка всего, что ниже, требует (в зависимости от ОС) системных вызовов или открытия символьных устройств в / dev. Стандартная библиотека Python не предоставляет для этого стандартного средства.

0 голосов
/ 11 апреля 2018

Взгляните на pynput модуль в 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()

Надеюсь, это поможет.

0 голосов
/ 26 октября 2016

эта функция вернет код для заглавного символа:

def upCcode( ch ):
    if(len(ch) == 1):
        return ord(ch.upper())

и это код символа нижнего регистра:

def lowCcode( ch ):
        if(len(ch) == 1):
            return ord(ch.lower())

этот способ намного проще, и вам не нужно импортировать внешние библиотеки.

Вам нужно будет выбрать один из двух методов для «некоторой функции», которую вы описали в своем вопросе. Вот пример:

ВЫВОД:

# when using upCode():
>> upCcode('a')
65

>> upCcode('A')
65

# when using lowCode():
>> lowCcode('a')
97

>> lowCcode('A')
97
0 голосов
/ 26 февраля 2009

Очевидный ответ:

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()
0 голосов
/ 22 февраля 2009

Если вам нужно работать только в Windows, попробуйте msvcrt .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...