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

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

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()

затем я запустил скрипт и нажал вверх вправо влево, что дало мне этот вывод:

$ 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.) Если нет, то как я должен хранить значения клавиш со стрелками?

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

2 ответов


кажется, я понял.

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

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

затем я заметил, что клавиша со стрелкой в 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()

Я использую 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)