はじめに
curses モジュールを使うことでキーの判定を取ることができます。それに依存しない方法を以下に書きます
https://docs.python.org/ja/3/library/curses.html#constants
まえがき
自分用のメモです。愚直実装です。
やりたいことは十字キーなど特殊な文字が入力されたことを検知することです。
前提としてUnicode制御文字の知識があることが望ましいです。
wikipedia
詰まったところ
getchは入力を1文字ごとに取得します。しかし、矢印キーは3回文字分の入力がありました。 例えば上矢印は27 91 65
とはいってきます。このままでは、矢印キーなどの特殊なキーを判定することができないばかりか、望まない入力を受け取ってしまいます。そこで、以下のように実装しました。
ソース
getch 1文字の入力を受け取る関数
ord は文字をUnicodeに変換する関数、
chr はUnicodeを文字に変換する関数です。
自分用のデバッグも兼ねて、冗長なコードになっています。
# inputの代わりに、1文字ずつ入力を受け取る関数を用意。
# try の中はWindows用、except 野中はLinux用
try:
from msvcrt import getch
except ImportError:
import sys
import tty
import termios
def getch():
fd = sys.stdin.fileno()
old = termios.tcgetattr(fd)
try:
tty.setraw(fd)
return sys.stdin.read(1)
finally:
termios.tcsetattr(fd, termios.TCSADRAIN, old)
# Unicode制御文字のエイリアス
EOT = 3
TAB = 9
ESC = 27
# メインループ
while True:
key = ord(getch())
if key == EOT:
break
elif key == TAB:
print('keydown TAB')
elif key == ESC:
key = ord(getch())
if key == ord('['):
key = ord(getch())
if key == ord('A'):
print('keydown uparrow')
continue
elif key == ord('B'):
print('keydown downarrow')
continue
elif key == ord('C'):
print('keydown leftarrow')
continue
elif key == ord('D'):
print('keydown rightarrow')
continue
else:
message = f'keydown {chr(key)}'
print(message)
実行した結果
終わりに
今回はコードが冗長になるため実装しませんでしたが、特殊なキーを入力したときのUnicodeを見て、条件分岐で全列挙すれば、判定がとれます。この記事の類似コードはアプリケーションを自作するときに役に立つかもしれません。他にいい書き方を知っている人がいたら教えてください。