一文字入力をしてみたい
input()関数はエンターキーを打たないと読み込んでくれないんです。
エンターキーを押すのを省きたいんですね。
ということでエンターキーを打つのを省く手段を検索しました。
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)
macの場合これでできるらしい
参考元:https://torina.top/detail/428/
実行
while True:
print('入力:',end='')
key = getch()
print(key)
# esc で終わり
if key == chr(27):
break
文字が消える!
入力:a
入力:f
[ここにカーソル]
できた・・けど、、
入力:
が消えてるがな!!
(一文字入力したら急に現れてあたかも最初からあったような感じだけど)
目標
入力:[ここにカーソル]
となってほしい
結論
while True:
print('\r入力:',end='')
key = getch()
print(key)
if key == chr(27):
break
\r
を消したくない文字のところにやれば入力:
が消えなかった!!
理由はよくわからないけど、試行錯誤の結果です。
どうやら\r
やら\n
などの文字をgetch()
の前にある文字列に入れておけば良さそう。
出力を強制する必要があるらしい(追記)
print('key :', end='', flush=True)
とやると表示できました。
なんでも、改行を出力するまで画面に反映されてないだとか、、
別のところでprint('key :', end='')
とやったら改行なしで出力されるから何のこっちゃ状態です。。
これで色々できそう
s = []
while 1:
print('\r'+''.join(s), end='')
char = getch()
# esc で終わり
if char == chr(27):
break
# enter 押すと\rが入力される? カーソルが左端になるので無視
elif char == chr(13):
continue
# backspace で一文字削除
elif char == chr(127):
if len(s) != 0:
s.pop()
print('\b ',end='')
continue
s.append(char)
print('')
これで一文字ずつ入力してるけどその都度表示することができた!
もう少し処理を加えれば打つと同時に小文字→大文字変換とかできると思う!すごい!