realtime non-blocking keyboard input

Erno Kuusela erno at iki.fi
Sat Jun 24 14:21:18 EDT 2000


>>>>> "Jp" == Jp Calderone <exarkun at flashmail.com> writes:

    Jp>  Any way *other* than using the curses library to check to see
    Jp> if a key has been pressed, and if so, which one?  Or any way
    Jp> to prevent curses.initscr() from messing w/ normal prints?

yep, you can do it with the termios module (or with system() & stty) if
you dare.

here is some code for one-key-at-a-time input that i had laying
around (might be borrowed from somewhere):

import termios, TERMIOS, sys, os

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 = None
        try:
                c = os.read(fd, 1)
        finally:
                termios.tcsetattr(fd, TERMIOS.TCSAFLUSH, old)
        return c

if __name__ == '__main__':
        print 'type something'
        s = ''
        while 1:
                c = getkey()
                if c == '\n':
                        break
                print 'got', c
                s = s + c

        print s

however this doesn't do it in a non-blocking way. you should
probably check for data with the select module prior to the read()
call. set the timeout to 0 and it returns immediately iirc.
(it's also possible to set stdin to non-blocking mode, or use the
FIONREAD ioctl, or ...)

  -- erno



More information about the Python-list mailing list