優れた軽量モジュール curtsies を使用すると、次のようなことができます (examples/ ディレクトリから取得):
from curtsies import Input
def main():
with Input(keynames='curses') as input_generator:
for e in input_generator:
print(repr(e))
if __name__ == '__main__':
main()
キーボードのキーを押すと、次のようになります。
'a'
's'
'KEY_F(1)'
'KEY_F(2)'
'KEY_F(3)'
'KEY_F(4)'
'KEY_F(5)'
'KEY_LEFT'
'KEY_DOWN'
'KEY_UP'
'KEY_RIGHT'
'KEY_NPAGE'
'\n'
curtsies は、端末関連の低レベルの抽象化として bpython によって使用されます。
入力をデコードする際の基本的な問題は、さまざまな端末と xterm
のような端末エミュレータ プログラムで発生することです。 または gnome-terminals
物理的に同じキーは、異なるキーコード シーケンスを生成します。そのため、入力をデコードするためにどの端末設定を使用する必要があるかを知る必要があります。このようなモジュールは、それらの悲惨な詳細を抽象化するのに役立ちます.
これは、単一の文字を取得するために stdin を raw モード (バッファリングを無効にするため、Enter キーを押す必要がありません) にする単純なループです。もっと賢いことをするべきです (with
のように) それを無効にするステートメント)が、ここでアイデアを得る:
import tty
import sys
import termios
orig_settings = termios.tcgetattr(sys.stdin)
tty.setcbreak(sys.stdin)
x = 0
while x != chr(27): # ESC
x=sys.stdin.read(1)[0]
print("You pressed", x)
termios.tcsetattr(sys.stdin, termios.TCSADRAIN, orig_settings)
Python で重要なリリースを検出するには、ループする必要があると思います。
ETA についての説明:
Linux では、プログラムへの入力はライン バッファになります .これは、オペレーティング システムが行全体が入力されるまで入力をバッファリングすることを意味するため、ユーザーが「Enter」を押すまで、ユーザーが入力したものはプログラムに表示されません。つまり、プログラムがユーザーに「w」と入力することを期待している場合、ユーザーがこれを実行すると、「w」はユーザーが「Enter」を押すまで OS のバッファーに留まります。この時点で、行全体がプログラムに配信されるため、文字列 "w\n" がユーザーの入力として取得されます。
これを無効にするには、tty を raw モード にします。 .これは、Python 関数 tty.setcbreak
で行います。 これにより、Linux の tty ドライバーが呼び出され、バッファリングを停止するように指示されます。 sys.stdin
を渡しました バッファリングをオフにしたいストリームを伝える引数。 tty.setcbreak
の後に 呼び出し、上記のループは、ユーザーが押すすべてのキーの出力を提供します.
ただし、複雑なことに、プログラムが終了すると、tty はまだ raw モードのままです。現代の端末設定が提供する力をまったく得られないため(制御またはエスケープシーケンスを使用する場合など)、通常、これは満足のいくものではありません。たとえば、ctrl-C
でプログラムを終了する際に問題が発生する可能性があることに注意してください。 .したがって、端末を cooked モード に戻す必要があります。 入力文字の読み取りが完了したら。 termios.tcsetattr
call は単に「端末を元の状態に戻してください」と言っているだけです。最初に termios.tcgetattr
を呼び出すことで、これを行う方法を知っています プログラムの冒頭で、「端末の現在の設定をすべて教えてください」と言っています。
すべてを理解すれば、プログラムに適した関数に機能を簡単にカプセル化できるはずです。
stdin
入力がユーザーから来るストリームです。ウィキペディアで、標準ストリームについて詳しく説明できます。