python3にもkbhit()とgetch()が欲しい
はじめに
何言語でプログラミングするにしろ、ユーザからのキーボード入力はよく使うだろう。 特によく使う方法は「通常はメインの処理をしていて、キーボード入力が何かあったときだけ、そのキーに応じて別の処理をする」というものである。 私はよくPICなどを使って電子工作しているが、そういったデバイスではあまり文字列処理はしない。1文字で十分である。
すなわち、kbhit()+getch()である。これさえあればOK。
最近はラズパイでpythonを使っているが、ラズパイでもそういった処理をする方法を紹介する。
kbhit.pyというものがある
やっぱりこういうことは誰でもやりたいと思うからか、ライブラリを作って公開してくれている人がいるので、それをありがたく使わせてもらう。
ただ、これをpython3でそのまま実行しようとすると以下のようなエラーが出る。
File "recipe-572182-1.py", line 33 return dr <> [] ^ SyntaxError: invalid syntax
この「<>」はpythonのnot equalの記号だが、python3では文法エラーになるようなので、それを修正したコードをここに書いておく。(といっても<>を!=に修正しただけ)
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 putch(ch): sys.stdout.write(ch) def getch(): return sys.stdin.read(1) def getche(): ch = getch() putch(ch) return ch def kbhit(): dr,dw,de = select([sys.stdin], [], [], 0) return dr != [] # ここだけ修正 if __name__ == '__main__': atexit.register(set_normal_term) set_curses_term() while 1: if kbhit(): ch = getch() break sys.stdout.write('.') print('done:'+ch)
実際にpython3のプログラムにインポートして使うときは、
from kbhit import *
でインポートして、初期化のときに以下のコードを実行
atexit.register(set_normal_term) set_curses_term()
そしたらあとは、
if kbhit():
ch = getch()
で好きなだけkbhit()+getch()できる。やったね。