Обработать клавиши стрелок в input/sys.stdin python
В функции input или при чтении из stdin в Python при попытке ввести стрелки (вправо и влево к примеру) выводится нечто типа ^[[A, мне нужно как-то их (клавиши стрелок) обработать без нажатия клавиши Return.
Ответы (2 шт):
Основано на примере отсюда: HOW TO IMPLEMENT KBHIT() ON LINUX (PYTHON RECIPE)
Вкратце: нужно перевести терминал в небуферизированный режим (чтобы read возвращал считанные символы сразу, не дожидаясь Enter), перед чтением проверять, есть ли что читать.
import sys, termios, atexit
from select import select
# save the terminal settings
fd = sys.stdin.fileno()
new_term = termios.tcgetattr(fd)
old_term = termios.tcgetattr(fd)
# new terminal setting unbuffered
new_term[3] = (new_term[3] & ~termios.ICANON & ~termios.ECHO)
# switch to normal terminal
def set_normal_term():
termios.tcsetattr(fd, termios.TCSAFLUSH, old_term)
# switch to unbuffered terminal
def set_curses_term():
termios.tcsetattr(fd, termios.TCSAFLUSH, new_term)
def kbhit():
dr,dw,de = select([sys.stdin], [], [], 0)
return dr != []
if __name__ == '__main__':
atexit.register(set_normal_term)
set_curses_term()
while True:
if kbhit():
key = sys.stdin.read(1)
if key == '\x1b':
# Если escape последовательность, то считать еще 2 символа
# Но будет некорректно работать, если был нажата клавиша Escape (будет ждать нажатия еще 2 кнопок)
key += sys.stdin.read(2)
print(repr(key))
if key == '\x1b[A':
print('Up')
elif key == '\x1b[B':
print('Down')
elif key == '\x1b[C':
print('Right')
elif key == '\x1b[D':
print('Left')
Очевидно, вариант с использованием библиотеки curses намного удобнее
Для линукс есть стандартный модуль curses (текстовые окна)
import curses
import os
def main(win):
win.nodelay(True)
key=""
win.clear()
win.addstr("Detected key:")
while 1:
try:
key = win.getkey()
win.clear()
win.addstr("Detected key:")
win.addstr(str(key))
if key == os.linesep:
break
except Exception as e:
# No input
pass
curses.wrapper(main)
^[[A это эскейп последовательность. Они не попадают на текстовый stdin. Их можно прочесть с tty, но это слишком много кода для такой операции.
Если интересует физическая клавиатура, то можно пофильтровать evdev через python-evdev