Trouver les Valeurs des Touches Fléchées en Python: Pourquoi sont-ils triples?
Je suis en train d'essayer de trouver les valeurs que mon système local attribue à l'aide des touches fléchées, plus précisément 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()
Puis j'ai exécuté le script, et de frapper en BAS à DROITE à GAUCHE, ce qui m'a donné ce résultat:
$ 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
C'est anormal, car elle suggère que les touches de direction sont enregistrés sous la forme d'une triple (27-91-6x) sur mon système, comme chaque pression sur une touche de direction prend les trois instances de get(). Par comparaison, en appuyant 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 ma flèche-clés semblent être stockées sous forme de triplets? Pourquoi est-ce si? Est-ce le même sur toutes les plateformes? (Je suis sous Linux Debian.) Si non, comment dois-je stocker les valeurs de la flèche-clés?
Le but ici est que je suis en train d'écrire un programme qui a besoin de reconnaître correctement aide des touches fléchées et d'effectuer une fonction de fonction de flèche touche a été pressée.
- Je dirais code d'échappement ANSI même si ça manque clairement une section sur les codes d'échappement qui sont envoyés par le clavier; leur format est le même que ceux qui sont envoyés à partir de programmes pour le terminal.
- Cela paraît utile: stackoverflow.com/questions/4130048/...
- Pourquoi avez-vous un
_Getch
classe avec un__call__
méthode au lieu de seulement ungetch
fonction? - parce que j'ai besoin de faire appel à une instance de celle-ci? Il ne fonctionne pas comme une fonction.
- Il fonctionne parfaitement comme une fonction. Il suffit de tourner la
__call__
méthode dans un niveau supérieurgetch
la fonction, supprimer laself
paramètre, et d'appelergetch()
au lieu de créer uninkey
instance et d'appelinkey()
. Même si vous devez passer autour d'un objet, vous pouvez le faire avec ungetch
fonction directement. - Il ressemble à la source d'origine-vous tiré de cette de besoin de faire quelques initialisation de travail afin de déterminer la mise en œuvre qu'à utiliser. Vous avez enlevé les OS de détection de travail et tout l'équipement nécessaire pour la soutenir, si une classe n'est plus nécessaire.
- J'ai fait exactement cela, et il ne fonctionne pas pour moi; si je fait une erreur quelque part.
- Vous avez fait une erreur quelque part. Je ne sais pas ce que l'erreur a été, mais il devrait avons travaillé.
- Vous avez raison. Je l'ai eu à travailler.
Vous devez vous connecter pour publier un commentaire.
Je pense que j'ai tout compris.
J'ai appris de ici que chaque touche de la flèche est représenté par un unique code d'échappement ANSI. Puis j'ai appris que l'échappement ANSI codes varier en fonction du système et des applications: dans mon terminal, frapper
cat
et en appuyant sur la flèche vers le haut donne^[[A
, en C il semble être\033[A
, etc. La dernière partie, la[A
, reste le même, mais le code de la précédenteEscape
peut être en hexadécimal(en commençant par un x), octal (commençant par 0), ou décimal(pas de plomb dans le nombre).Puis j'ai ouvert la console python, et branché dans les triples j'avais déjà reçu, en essayant de trouver leurs valeurs de caractère. Comme il s'est avéré,
chr(27)
a donné\x1b
,chr(91)
a donné[
, et en appelantchr
sur65,66,67,68
retournéA,B,C,D
respectivement. Ensuite, il a été clair:\x1b
a été la fuite de code!Puis j'ai noté qu'une touche de la flèche, dans la norme ANSI représenté comme un triple, est bien sûr représenté que trois personnages, j'ai donc besoin de modifier mon code comme suit dans les trois caractères à la fois. Voici le résultat:
for
boucle dans le _Getch de la fonction si.elif
, et de regarder pour des signaux tels que ctrl+c. Cependant, il ya des façons plus faciles de le faire.raw
mode les caractères de contrôle pour ctrl-c sont traités comme des caractères d'entrée. Pour garder le "par défaut" comportement de la touche ctrl+c on a besoin de définir cbreak mode (tty.setcbreak(...)
) à la place. Pour le ctrl+c fonctionne dans mon expérience, mais je ne peux pas dire sur les autres séquences de contrôle.\x27
) et la séquence d'Échappement code (également\x27
) qui s'attend à plus de caractères?Je suis à l'aide de Mac et j'ai utilisé le code suivant et il a bien fonctionné:
J'ai obtenu les valeurs de mes touches fléchées 0,1,2,3 (Haut, Bas, Gauche, Droite):
Toujours bon de se rappeler le code 27 la touche ESC trop.
En ce qui concerne meilleur!
key
peut obtenir une infinité de255
.