0
0

More than 3 years have passed since last update.

Enter無し一文字入力しようとすると文字が消えてまう現象

Last updated at Posted at 2020-05-10

一文字入力をしてみたい

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('')

これで一文字ずつ入力してるけどその都度表示することができた!
もう少し処理を加えれば打つと同時に小文字→大文字変換とかできると思う!すごい!

0
0
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0