Подтвердить что ты не робот

Поиск значений клавиш со стрелками в Python: почему они являются тройками?

Я пытаюсь найти значения, которые моя локальная система назначает клавишам со стрелками, в частности, на Python. Для этого я использую следующий script:

import sys,tty,termios
class _Getch:       
    def __call__(self):
            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

def get():
    inkey = _Getch()
    while(1):
            k=inkey()
            if k!='':break
    print 'you pressed', ord(k)

def main():
    for i in range(0,25):
        get()

if __name__=='__main__':
    main()

Затем я запустил script и нажал UP DOWN RIGHT LEFT, который дал мне этот результат:

$ python getchar.py 
you pressed 27
you pressed 91
you pressed 65
you pressed 27
you pressed 91
you pressed 66
you pressed 27
you pressed 91
you pressed 67
you pressed 27
you pressed 91
you pressed 68

Это аномально, потому что это говорит о том, что клавиши со стрелкой зарегистрированы как некоторая форма тройки (27-91-6x) в моей системе, так как каждое нажатие клавиши со стрелкой занимает три экземпляра get(). Для сравнения, нажатие a, b, c и CTRL-C дает:

you pressed 97
you pressed 98
you pressed 99
you pressed 3

Может ли кто-нибудь объяснить мне, почему значения моих клавиш-стрелок, кажется, хранятся как тройки? Почему это так? Это одно и то же на всех платформах? (Я использую Debian Linux.) Если нет, как мне нужно хранить значения клавиш со стрелками?

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

4b9b3361

Ответ 1

Я думаю, что понял.

Я узнал из здесь, что каждая клавиша стрелки представлена ​​уникальным кодом escape ANSI. Затем я узнал, что коды выхода ANSI различаются в зависимости от системы и приложения: в моем терминале, нажав cat и нажав стрелку вверх, вы получите ^[[A, в C это, кажется, \033[A и т.д. Последняя часть, [A, остается прежним, но код для предыдущего Escape может быть в шестнадцатеричном формате (начиная с x), восьмеричном (начиная с 0) или десятичном (нет числа в числе).

Затем я открыл консоль python и подключил троек, которые я ранее получил, пытаясь найти их значения символов. Как оказалось, chr(27) дал \x1b, chr(91) дал [, а вызов chr на 65,66,67,68 вернулся A,B,C,D соответственно. Тогда было ясно: \x1b был escape-кодом!

Тогда я заметил, что клавиша со стрелкой в ​​ANSI, представленная как тройка, конечно, представлена ​​в виде трех символов, поэтому мне нужно было изменить свой код, чтобы читать по три символа за раз. Вот результат:

import sys,tty,termios
class _Getch:
    def __call__(self):
            fd = sys.stdin.fileno()
            old_settings = termios.tcgetattr(fd)
            try:
                tty.setraw(sys.stdin.fileno())
                ch = sys.stdin.read(3)
            finally:
                termios.tcsetattr(fd, termios.TCSADRAIN, old_settings)
            return ch

def get():
        inkey = _Getch()
        while(1):
                k=inkey()
                if k!='':break
        if k=='\x1b[A':
                print "up"
        elif k=='\x1b[B':
                print "down"
        elif k=='\x1b[C':
                print "right"
        elif k=='\x1b[D':
                print "left"
        else:
                print "not an arrow key!"

def main():
        for i in range(0,20):
                get()

if __name__=='__main__':
        main()

Ответ 2

Я использую Mac, и я использовал следующий код, и он работал хорошо: Я получил значения для клавиш со стрелками как 0,1,2,3 (Вверх, Вниз, Влево, Вправо): Всегда полезно запомнить код 27 для клавиши ESC. С наилучшими пожеланиями!

while True:
    key = cv2.waitKey(1) & 0xFF

    # if the 'ESC' key is pressed, Quit
    if key == 27:
        quit()
    if key == 0:
        print "up"
    elif key == 1:
        print "down"
    elif key == 2:
        print "left"
    elif key == 3:
        print "right"
    # 255 is what the console returns when there is no key press...
    elif key != 255:
        print(key)