Does one have to use curses to read single characters from keyboard?
Barry Scott
barry at barrys-emacs.org
Sun Dec 11 17:22:45 EST 2022
> On 11 Dec 2022, at 18:50, Chris Green <cl at isbd.net> wrote:
>
> My solution in the end was copied from one I found that was much
> simpler and straightforward than most. I meant to post this earlier
> but it got lost somewhere:-
>
> import sys, termios, tty
> #
> #
> # Read a single character from teminal, specifically for 'Y/N'
> #
> fdInput = sys.stdin.fileno()
> termAttr = termios.tcgetattr(0)
> #
> #
> # Get a single character, setcbreak rather than setraw meands CTRL/C
> etc. still work
> #
> def getch():
> sys.stdout.flush()
> tty.setcbreak(fdInput)
> ch = sys.stdin.buffer.raw.read(1).decode(sys.stdin.encoding)
Will not work for uncode code points above 255.
This is what happened when I typed € key:
:>>> a.getch()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/private/var/folders/ll/08dwwqkx6v9bcd15sh06x14w0000gn/T/a.py", line 15, in getch
ch = sys.stdin.buffer.raw.read(1).decode(sys.stdin.encoding)
UnicodeDecodeError: 'utf-8' codec can't decode byte 0xe2 in position 0: unexpected end of data
You would need to have a loop that collected all the utf-8 bytes of a single code point.
You can to look at the first byte of know if the utf-8 is 1, 2, 3 or 4 bytes for a code point.
Barry
> termios.tcsetattr(fdInput, termios.TCSAFLUSH, termAttr)
> sys.stdout.write(ch)
> return ch
> #
> #
> # Get a y or n answer, ignore other characters
> #
> def getyn():
> ch = 'x'
> while ch != 'y' and ch != 'n':
> ch = getch().lower()
> return ch
>
> So getyn() reads a y or an n, ignores anything else and doesn't wait
> for a return key. Keyboard input operation is restored to normal
> after doing this. Using tty.setcbreak() rather than tty.setraw() means
> that CTRL/C etc. still work if things go really wrong.
>
>
> --
> Chris Green
> ·
> --
> https://mail.python.org/mailman/listinfo/python-list
More information about the Python-list
mailing list