msvcrt
has a handy function for this: kbhit()
. Unix doesn't :(
I have a function _Getch()
like:
def _Getch():
if sys.stdin.isatty():
fd = sys.stdin.fileno()
old_settings = termios.tcgetattr(fd)
try:
tty.setraw(sys.stdin.fileno())
ch = sys.stdin.read(1)
finally:
termios.tcsetattr(fd, termios.TCSADRAIN, old_settings)
return ch
else:
return sys.stdin.read(1)
It gets exactly one keypress.
The problem comes when someone presses:
ESC sends
\x1b
. That's 1 byte: the actual escape character.Page Up sends
\x1b[H
. That's 3 bytes.F2 sends
\x1b[OQ
. That's 4 bytes.F5 sends
\x1b[15~
. That's 5 bytes.
See where this is going? Once ESC has been read, there is no predicting how long the following sequence will be.
Subsequent _Getch()
calls will get these bytes, but the question is of how many _Getch()
calls.
I want to define a function like the following, which will read everything waiting in stdin
til there's nothing left:
def _Kbhit():
y = []
while msvcrt.kbhit(): # while something is waiting
y.append(msvcrt.getch()) # get it!
return y
Here's the Unix equivalent that is my aim (from here):
def _Kbhit():
fd = sys.stdin.fileno()
fl = fcntl.fcntl(fd, fcntl.F_GETFL)
fcntl.fcntl(fd, fcntl.F_SETFL, fl | os.O_NONBLOCK)
return sys.stdin.read(waiting_buffer_len) # ?
I just don't know how to define waiting_buffer_len
.
I've searched through all the relevant docs (tty
, termios
, sys.stdin
, fcntl
, os
), but I can't find what I'm looking for.