Unbuffered non-blocking keyboard input on command line

☆樱花仙子☆ 提交于 2019-12-23 22:07:58

问题


I want to capture "all" keyboard input on the command line immediately (without waiting for a new line) in a non-blocking way.

This question demonstrates how you can read from stdin in a non-blocking way using select(). This is how it works:

while True:
    if select.select([sys.stdin], [], [], 0)[0] == [sys.stdin]:
        print(sys.stdin.read(1))

    ... do other stuff ...

Unfortunately you only get results after pressing RETURN.

My first guess was that stdin is just line buffered so after reading this question I turned my code into

ubuf_stdin = os.fdopen(sys.stdin.fileno(), 'rb', buffering=0)
while True:
    if select.select([ubuf_stdin], [], [], 0)[0] == [ubuf_stdin]:
        print(ubuf_stdin.read(1))
    ... do other stuff ...

This code works better - the buffer is being read completely without interruptions - but it still waits for RETURN being pressed.

I also tried to detach stdin:

ubuf_stdin = os.fdopen(sys.stdin.detach().fileno(), 'rb', buffering=0)

How do I react on keyboard input immediately after a key press?


回答1:


Use the getch module to get a single keypress at a time, as described in this question.

I don't think you'll be able to read stdin in a non-blocking-yet-character-at-a-time way, it's really not intended for that purpose.




回答2:


Ok this one does it but it has some disadvantages yet:

  • uses the curses module which seems a bit heavy to me
  • input has to be polled - no way to select() yet.
  • the keyboard input still gets printed to the terminal

.. but it works :).

import curses
def read_stdin(self):
    def cb(screen):
        result = []
        screen.nodelay(1)
        while True:
            try:
                result.append(screen.getkey())
            except curses.error:
                return result

    # contains a list of keys pressed since last call
    return curses.wrapper(cb)


来源:https://stackoverflow.com/questions/36066830/unbuffered-non-blocking-keyboard-input-on-command-line

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!