web-dev-qa-db-fra.com

Trouver les valeurs des touches fléchées en Python: pourquoi sont-elles des triplets?

J'essaie de trouver les valeurs que mon système local attribue aux touches fléchées, en particulier en Python. J'utilise le script suivant pour ce faire:

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

Ensuite, j'ai exécuté le script et j'ai frappé UP DOWN RIGHT LEFT, ce qui m'a donné cette sortie:

$ 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

Ceci est anormal car cela suggère que les touches fléchées sont enregistrées comme une forme de triple (27-91-6x) sur mon système, car chaque pression sur une touche flèche prend trois instances de get (). Par comparaison, appuyer sur a, b, c et CTRL-C donne:

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

Quelqu'un peut-il m'expliquer pourquoi les valeurs de mes touches fléchées semblent être stockées sous forme de triplets? Pourquoi en est-il ainsi? Est-ce la même chose sur toutes les plateformes? (J'utilise Debian Linux.) Sinon, comment dois-je procéder pour stocker les valeurs des touches fléchées?

L'objectif final ici est que j'essaie d'écrire un programme qui doit reconnaître correctement les touches fléchées et exécuter une fonction en fonction de la touche fléchée qui a été enfoncée.

26
Newb

Je pense que je l'ai compris.

J'ai appris de ici que chaque touche fléchée est représentée par un code d'échappement ANSI unique. J'ai ensuite appris que les codes d'échappement ANSI varient selon le système et l'application: dans mon terminal, appuyer sur cat et appuyer sur la flèche vers le haut donne ^[[A, En C, il semble que \033[A, etc. La dernière partie, le [A, reste la même, mais le code du Escape précédent peut être en hexadécimal (commençant par un x), octal (commençant par un 0) ou décimal (pas de plomb dans le nombre).

Ensuite, j'ai ouvert la console python, et branché les triplets que j'avais précédemment reçus, essayant de trouver leurs valeurs de caractères. Il s'est avéré que chr(27) a donné \x1b, chr(91) a donné [ et l'appel de chr sur 65,66,67,68 a retourné A,B,C,D respectivement. Ensuite, il était clair: \x1b Était le code d'échappement!

Ensuite, j'ai remarqué qu'une touche fléchée, dans ANSI représentée comme un triple, est bien sûr représentée comme trois caractères, j'ai donc dû modifier mon code afin de lire en trois caractères à la fois. Voici le résultat:

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

J'utilise Mac et j'ai utilisé le code suivant et cela a bien fonctionné: j'ai obtenu les valeurs pour mes touches fléchées comme 0,1,2,3 (haut, bas, gauche, droite): toujours bon de se rappeler le code 27 pour la touche ESC aussi. Meilleures salutations!

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)
4
Mauricio Alo