user3565923
user3565923

Reputation: 340

Reading and printing one char at a time - getche() and backspace in Python

I want to create typing training program. I need a function which immediately both reads and prints each character user hits - something like getche()

I have tried using getche from this module but it doesn't deal well with backspaces. When I hit backspace it prints ^? to the console and I want it to delete characters.

Upvotes: 2

Views: 455

Answers (2)

J_H
J_H

Reputation: 20450

The docs are pretty clear.

tried using getche

Don't do that, as getche() is documented to have the behavior that you say you don't want.

Call getch(), and assume responsibility for "echoing" or otherwise maintaining the display according to your requirements.

For example, this code accomplishes what you want:

from getch import getch


def pr(s):
    print(s, end='', flush=True)


def get_word():
    DELETE = 127  # ASCII code
    word = ''
    c = ''
    while not c.isspace():
        c = getch()
        if ord(c) == DELETE:
            pr('\r' + ' ' * len(word) + '\r')
            word = word[:-1]
            pr(word)
        if c.isprintable():
            word += c
            pr(c)
    print('\n')
    return word

Upvotes: 1

ch0wner
ch0wner

Reputation: 349

From the official curses documentation page it's definition is:

The curses module provides an interface to the curses library, the de-facto standard for portable advanced terminal handling.

You said you wanted to write a typing training program, well I think the best solution is to use the curses library for such task.

On UNIX systems it comes with the default installation of python, and if you are targeting windows systems I have found windows-curses to add support greatly.

Basically you can find a HOWTO guide in this page from the official docs.

Here's an example usage the creates a textbox widget

The curses.textpad module should be very useful for you.

import curses
from curses import wrapper
from curses.textpad import Textbox, rectangle

def main(stdscr):   
    stdscr.addstr(0, 0, "Enter IM message: (hit Ctrl-G to send)")

    editwin = curses.newwin(5,30, 2,1)
    rectangle(stdscr, 1,0, 1+5+1, 1+30+1)
    stdscr.refresh()

    box = Textbox(editwin)

    # Let the user edit until Ctrl-G is struck.
    box.edit()

    # Get resulting contents
    message = box.gather()
    print(message)

if __name__ == '__main__':
    wrapper(main)

Here's what it looks like using the windows-curses module

Curses example screenshot

You can do many things using this library, I suggest you go on and read the docs on the links I have provided.

Upvotes: 1

Related Questions