Search code examples
pythonpython-2.7curses

Use curses to detect user input immediately


I'm using curses in python2.7 to control a robot. I would like to steer it with e.g. the w key, to tell it it should go forward. Here's my code, stripped away of all robot controls:

import curses
from time import sleep

if __name__ == "__main__":
    shell = curses.initscr()
    shell.nodelay(True)

    while True:
        key = shell.getch()

        if key == 119:
            print("key w pressed")

        sleep(0.03)

That works fine, except that I have to press enter for the key to be recognized. So I can press w several times, and when I press enter, the robot does exactly what it's supposed to do, or in this example, the text key w pressed appears as many times as I have pressed it. But I would like this to happen immediately, i.e. without having to press enter. How can this be achieved?


Solution

  • add curses.cbreak() to your setup, and when you cleanup call curses.nocbreak() to restore the terminal to a usable state.

    You can do the cleanup by catching ctrl-c as an exception. Eg:

     try:
         curses.cbreak()
         while True:
                key = shell.getch()
                if key == 119:
                    print("key w pressed")
                sleep(0.03)
     except KeyboardInterrupt:
         curses.nocbreak()