Tuesday, March 30, 2010

getch() in Python - get a single character from keyboard

Today I needed to write a Python code for 'Press any key to continue' feature. First I wrote the code: raw_input("Press Any Key to Continue: ")
But actually it's not any key, you have to press enter followed by any key (or just enter). Then I started searching Google, came across several links, tried some of those and finally got something which is very close to what I need and modified the code to fit into my need. Here is the link that was almost exactly what I needed: http://pyfaq.infogami.com/how-do-i-get-a-single-keypress-at-a-time

Here is my getch function in Python:

import sys
import termios
import fcntl

def myGetch():
fd = sys.stdin.fileno()

oldterm = termios.tcgetattr(fd)
newattr = termios.tcgetattr(fd)
newattr[3] = newattr[3] & ~termios.ICANON & ~termios.ECHO
termios.tcsetattr(fd, termios.TCSANOW, newattr)

oldflags = fcntl.fcntl(fd, fcntl.F_GETFL)
fcntl.fcntl(fd, fcntl.F_SETFL, oldflags | os.O_NONBLOCK)

while 1:
c = sys.stdin.read(1)
except IOError: pass
termios.tcsetattr(fd, termios.TCSAFLUSH, oldterm)
fcntl.fcntl(fd, fcntl.F_SETFL, oldflags)

And this one is also interesting but I couldn't make it work: getch()-like unbuffered character reading from stdin on both Windows and Unix (Python)


Tyler said...

You might want to add a "return c" at the end of that function.

Goofy-2 said...

This worked OK under Linux, but needed to add in the script:
import os
And indeed at the end of the function:
return c

erik said...

Fixed and cleaned up the code snippet: https://gist.github.com/eallik/6751903