Опрос клавиатуры (обнаружение нажатия клавиши) в python



Answers


import sys
import select

def heardEnter():
    i,o,e = select.select([sys.stdin],[],[],0.0001)
    for s in i:
        if s == sys.stdin:
            input = sys.stdin.readline()
            return True
    return False
Question

Как я могу опросить клавиатуру из консольного приложения python? В частности, я хотел бы сделать что-то похожее на это из-за множества других операций ввода-вывода (выбор сокетов, доступ к последовательному порту и т. Д.):

   while 1:
      # doing amazing pythonic embedded stuff
      # ...

      # periodically do a non-blocking check to see if
      # we are being told to do something else
      x = keyboard.read(1000, timeout = 0)

      if len(x):
          # ok, some key got pressed
          # do something

Каков правильный питонический способ сделать это в Windows? Кроме того, переносимость в Linux не будет плохой, хотя это не требуется.




Если вы комбинируете time.sleep, threading.Thread и sys.stdin.read, вы можете легко подождать определенное количество времени для ввода, а затем продолжить, также это должно быть кросс-платформенная совместимость.

t = threading.Thread(target=sys.stdin.read(1) args=(1,))
t.start()
time.sleep(5)
t.join()

Вы также можете поместить это в такую ​​функцию

def timed_getch(self, bytes=1, timeout=1):
    t = threading.Thread(target=sys.stdin.read, args=(bytes,))
    t.start()
    time.sleep(timeout)
    t.join()
    del t

Хотя это ничего не вернет, вместо этого вы должны использовать модуль многопроцессорного пула, который вы можете найти здесь: как получить возвращаемое значение из потока в python?




Вы можете посмотреть, как pygame обрабатывает это, чтобы украсть некоторые идеи.




Решение с использованием модуля curses. Печать числового значения, соответствующего каждой нажатой клавише:

import curses

def main(stdscr):
    # do not wait for input when calling getch
    stdscr.nodelay(1)
    while True:
        # get keyboard input, returns -1 if none available
        c = stdscr.getch()
        if c != -1:
            # print numeric value
            stdscr.addstr(str(c) + ' ')
            stdscr.refresh()
            # return curser to start position
            stdscr.move(0, 0)

if __name__ == '__main__':
    curses.wrapper(main)



Related