Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Finding the Values of the Arrow Keys in Python: Why are they triples?

I am trying to find the values that my local system assigns to the arrow keys, specifically in Python. I am using the following script to do this:

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

Then I ran the script, and hit UP DOWN RIGHT LEFT, which gave me this output:

$ 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 

This is anomalous because it suggests that the arrow keys are registered as some form of triple (27-91-6x) on my system, as each press of an arrow key takes up three instances of get(). By comparison, pressing a,b,c and CTRL-C gives:

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

Can anyone explain to me why the values of my arrow-keys seem to be stored as triples? Why is this is so? Is this the same across all platforms? (I'm using Debian Linux.) If not, how should I go about storing the values of the arrow-keys?

The end goal here is in that I'm trying to write a program which needs to correctly recognize arrow-keys and perform a function depending on which arrow-key was pressed.

like image 866
Newb Avatar asked Mar 14 '14 05:03

Newb


People also ask

What are the arrow keys in Python?

K_UP , K_DOWN , K_LEFT , and K_RIGHT correspond to the arrow keys on the keyboard. If the dictionary entry for that key is True , then that key is down, and you move the player .

How do I use arrow keys in vi editor?

vi does not support arrow keys in insert mode. Use vim. Although your vi may just be a link to vim, it may be configured to behave like the "original" vi and thus disables the arrow keys. Just invoke vim directly.


2 Answers

I think I figured it out.

I learned from here that each arrow key is represented by a unique ANSI escape code. Then I learned that the ANSI escape codes vary by system and application: in my terminal, hitting cat and pressing the up-arrow gives ^[[A, in C it seems to be \033[A, etc. The latter part, the [A, remains the same, but the code for the preceding Escape can be in hex(beginning with an x), octal (beginning with a 0), or decimal(no lead in number).

Then I opened the python console, and plugged in the triples I had previously received, trying to find their character values. As it turned out, chr(27) gave \x1b, chr(91) gave [, and calling chr on 65,66,67,68 returned A,B,C,D respectively. Then it was clear: \x1b was the escape-code!

Then I noted that an arrow key, in ANSI represented as a triple, is of course represented as three characters, so I needed to amend my code so as to read in three characters at a time. Here is the result:

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() 
like image 183
Newb Avatar answered Oct 03 '22 01:10

Newb


I am using Mac and I used the following code and it worked well: I got the values for my arrow keys as 0,1,2,3 (Up, Down, Left, Right): Always good to remember code 27 for ESC key too. Best regards!

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) 
like image 20
Mauricio Alo Avatar answered Oct 03 '22 00:10

Mauricio Alo