I'm trying to write a program that needs to detect key presses, which I've already done using this code I found online:

TERMIOS = termios
def getkey():
   fd = sys.stdin.fileno()
   old = termios.tcgetattr(fd)
   new = termios.tcgetattr(fd)
   new[3] = new[3] & ~TERMIOS.ICANON & ~TERMIOS.ECHO
   new[6][TERMIOS.VMIN] = 1
   new[6][TERMIOS.VTIME] = 0
   termios.tcsetattr(fd, TERMIOS.TCSANOW, new)
   c = ''
   try:
      c = repr(sys.stdin.read(1))
   finally:
      termios.tcsetattr(fd, TERMIOS.TCSAFLUSH, old)
   return c

But I can't seem to find any good way to make it send back a string ("no keypress" or something like that, for example) if it doesn't detect any key press within a certain time period. Anyone have any ideas? I'm using python 2.7.3 on ubuntu 12.03. Thanks.

Recommended Answers

All 2 Replies

Adding a call to select.select() with a timeout works for me

import select
import sys
import termios

class TimeoutError(Exception):
    pass

TERMIOS = termios
def getkey():
    fd = sys.stdin.fileno()
    old = termios.tcgetattr(fd)
    new = termios.tcgetattr(fd)
    new[3] = new[3] & ~TERMIOS.ICANON & ~TERMIOS.ECHO
    new[6][TERMIOS.VMIN] = 1
    new[6][TERMIOS.VTIME] = 0
    termios.tcsetattr(fd, TERMIOS.TCSANOW, new)
    c = ''
    try:
        r, w, x = select.select([fd], [], [], 2.0)
        if r:
           c = repr(sys.stdin.read(1))
        else:
            raise TimeoutError
    finally:
        termios.tcsetattr(fd, TERMIOS.TCSAFLUSH, old)
    return c

if __name__ == "__main__":
    print getkey()

All this code is linux only! Please, indent python code with 4 spaces instead of 3, as most people do (read PEP 8).

Thanks, that worked nicely.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.