21

Possible Duplicate:
Python read a single character from the user

I am looking to be able to control a robot with the arrow keys using python. And my idea was to implement code that looked something like this...

#!/usr/bin/env python
# control a robot using python
exit = 0
while exit == 0:
  keypress = ##get keypress, if no key is pressed, continue##
  if keypress == 'q':
    exit = 1
    break
  elif keypress == KEY_UP:
    ##robot move forward##
  elif keypress == KEY_DOWN:
    ##robot move backward##
print "DONE"

However the problem is that I do not know how to get the users input. And I cannot use a GUI based solution like pygame from what I have found because the robot does not use a display.

Any help is very much appreciated!!

Community
  • 1
  • 1
sonfollower
  • 1,047
  • 2
  • 10
  • 20
  • Identical to [this question](http://stackoverflow.com/questions/510357/python-read-a-single-character-from-the-user), which has several solutions. – Junuxx May 21 '12 at 22:05
  • You might want to look into [`curses`](http://docs.python.org/library/curses.html). – Gareth Latty May 21 '12 at 22:05
  • I was looking at that question, but could not figure out if it was what I was looking for or not because I am looking for a linux solution and that seemed really complicated because of the cross-platform needs. I looked at curses, but does anyone know of a good tutorial on how to use it? The best I could find was the Python Docs and they only went so far. – sonfollower May 21 '12 at 23:34
  • 1
    There are a lot of answers to this question on SO. One of which explains that just trying to get a couple key press events makes curses a bit of overkill, and that you can simply read from stdin and interpret the keys. http://stackoverflow.com/a/7264312/496445 – jdi May 22 '12 at 00:06

1 Answers1

37

A simple curses example. See the docs for the curses module for details.

import curses
stdscr = curses.initscr()
curses.cbreak()
stdscr.keypad(1)

stdscr.addstr(0,10,"Hit 'q' to quit")
stdscr.refresh()

key = ''
while key != ord('q'):
    key = stdscr.getch()
    stdscr.addch(20,25,key)
    stdscr.refresh()
    if key == curses.KEY_UP: 
        stdscr.addstr(2, 20, "Up")
    elif key == curses.KEY_DOWN: 
        stdscr.addstr(3, 20, "Down")

curses.endwin()
allyourcode
  • 21,871
  • 18
  • 78
  • 106
dwblas
  • 386
  • 3
  • 2
  • Why is it that two letters get displayed when I hit a letter key once? It looks like getch moves cursor to the right of where addch puts it. Therefore, when I hit the next key, it gets displayed to the left of 20, 25, and then addch displays the same letter at 20, 25, leaving two characters on the screen. I guess getch does not prevent the letter to the right of 20, 25 from being displayed? How can I disable what I entered from being displayed? – allyourcode Dec 14 '16 at 20:50
  • 3
    allyourcode - add `curses.noecho()` (after the call to `cbreak` is good). Then curses won't autoprint the key, only the script will. – Ian Jun 16 '17 at 17:44
  • Simpler solution is to use [sshkeyboard](https://sshkeyboard.readthedocs.io/en/latest/). It requires less coding than curses, and it is a cross platform solution. – ilon Oct 28 '21 at 07:54