问题
Because I didn't find a better way to read keystrokes on command line I'm currently using getch()
.
Unfortunately using getch()
like this stops output on stdout
:
while True:
handle_keystroke(getch())
Pressing buttons triggers handle_keystroke()
and stdout
is being printed in the terminal - line by line for each keystroke.
Recommendations provided here didn't help.
What do I do wrong?
Btw: I do not need to use getch()
. Is there a better way (e.g. using select()
)?
Update: (changed the title)
All this becomes a problem only when you're using more than one thread. So it looks like getch
(which is a non Python function) doesn't release the GIL, so all other threads are suspended, so not only stdout
is affected.
回答1:
Ok, found a way to use select
instead of getch()
. The trick is to set the mode of sys.stdout
to cbreak
:
import select
import tty
import termios
from contextlib import contextmanager
@contextmanager
def cbreak(stream):
"""Set fd mode to cbreak"""
old_settings = termios.tcgetattr(stream)
tty.setcbreak(stream.fileno())
yield
termios.tcsetattr(stream, termios.TCSADRAIN, old_settings)
with cbreak(sys.stdin):
while True:
select.select([sys.stdin], [], []) == ([sys.stdin], [], [])
key = sys.stdin.read(1)
handle_keystroke(key)
来源:https://stackoverflow.com/questions/61098253/how-to-read-single-keystrokes-without-blocking-the-whole-application