Welcome, guest | Sign In | My Account | Store | Cart

kbhit on linux, the sample just prints dots until you press any key. I updated the sample to show how to implement unbuffered getch and getche safely.

Python, 45 lines
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
import sys, termios, atexit
from select import select

# save the terminal settings
fd = sys.stdin.fileno()
new_term = termios.tcgetattr(fd)
old_term = termios.tcgetattr(fd)

# new terminal setting unbuffered
new_term[3] = (new_term[3] & ~termios.ICANON & ~termios.ECHO)

# switch to normal terminal
def set_normal_term():
    termios.tcsetattr(fd, termios.TCSAFLUSH, old_term)

# switch to unbuffered terminal
def set_curses_term():
    termios.tcsetattr(fd, termios.TCSAFLUSH, new_term)

def putch(ch):
    sys.stdout.write(ch)

def getch():
    return sys.stdin.read(1)

def getche():
    ch = getch()
    putch(ch)
    return ch

def kbhit():
    dr,dw,de = select([sys.stdin], [], [], 0)
    return dr <> []

if __name__ == '__main__':
    atexit.register(set_normal_term)
    set_curses_term()

    while 1:
        if kbhit():
            ch = getch()
            break
        sys.stdout.write('.')

    print 'done'

Why? Maybe you want to know if the user is typing before you bother to perform a getch().

Context? The sort of situation you would use this in is where you need non-blocking keyboard input. This example essentially peeks at the keyboard buffer to see if there is any text available without blocking.

The example with the dots is lousy, but it suffices. I'm absolutely certain you'll put it to better use. I hope this helps someone.

Note: In my example I force the terminal back to its original buffered state. However, if you ever accidently forget to do this yourself, keep in mind you can still type 'reset' at the Linux prompt to get things back to normal. As you are typing it you will not see the text, but it is being typed so do not worry.