Move the Cursor Back For taking Input Python

妖精的绣舞 提交于 2021-02-07 10:42:07

问题


I was trying to do like the following:

a = input('Enter your name:_____________________________________________')

but here, the cursor is positioned at :

Enter your name:_____________________________________________
                                                             ^
                                                            Here

How do I position the cursor at:

Enter your name:_____________________________________________
                ^
               Here

I'm doing this on IDLE. (Command prompt is also appreciated :) )


回答1:


Having looked at this further, my final solution is to create my own custom input. NB: this only works in windows command prompt. If you are looking to do this in Unix you will have to look into an alternative. I may update this answer later to support Unix. [Edit: Updated to support both Unix and Windows]

Again, this will not work in IDLE

This function takes a prefix for your input, the number of max_length of the input, and the blank_char to fill the length of the input with.

First, we capture the user input and if it is a displayable character, we add it to our word. Every time we get a new character we overwrite the existing input line to keep up to date with the current state of the word.

We also look for the b'\x08' charater (backspace) so we can remove the last character from our word, and the return charcter to see if our user has pressed Enter.

Once enter has been pressed, return the word.

There is also a built in limit, where the user can only input as many characters as there are underscores, as this will cause letters to linger, you can always modify this by incrementing the number of underscores or something similar.

WINDOWS ONLY:

import msvcrt


def windows_get_input(prefix="", underscores=20, blank_char='_'):

    word = ""

    print(prefix + (underscores - len(word)) * blank_char, end='\r', flush=True)
    # Reprint prefix to move cursor
    print(prefix, end="", flush=True)

    while True:
        ch = msvcrt.getch()
        if ch in b'\x08':
            # Remove character if backspace
            word = word[:-1]
        elif ch in b'\r':
            # break if enter pressed
            break
        else:
            if len(word) == underscores:
                continue
            try:
                char = str(ch.decode("utf-8"))
            except:
                continue
            word += str(char)
        # Print `\r` to return to start of line and then print prefix, word and underscores.
        print('\r' + prefix + word + (underscores - len(word)) * blank_char, end='\r', flush=True)
        # Reprint prefix and word to move cursor
        print(prefix + word, end="", flush=True)
    print()
    return word

print(windows_get_input("Name: ", 20, '_'))

Handling both Windows and Unix

WINDOWS and UNIX:

def unix_getch():
    import termios
    import sys, tty
    def _getch():
        fd = sys.stdin.fileno()
        old_settings = termios.tcgetattr(fd)
        try:
            tty.setraw(fd)
            ch = sys.stdin.read(1)
        finally:
            termios.tcsetattr(fd, termios.TCSADRAIN, old_settings)
        return ch.encode("utf-8")
    return _getch()

def get_input(prefix="", underscores=20, blank_char='_'):

    word = ""

    try:
        import msvcrt
        func = msvcrt.getch
    except:
        func = unix_getch

    print(prefix + (underscores - len(word)) * blank_char, end='\r', flush=True)
    # Reprint prefix to move cursor
    print(prefix, end="", flush=True)

    while True:
        ch = func()
        if ch in b'\x08\x7f':
            # Remove character if backspace
            word = word[:-1]
        elif ch in b'\r':
            # break if enter pressed
            break
        else:
            if len(word) == underscores:
                continue
            try:
                char = str(ch.decode("utf-8"))
            except:
                continue
            word += str(char)
        # Print `\r` to return to start of line and then print prefix, word and underscores.
        print('\r' + prefix + word + (underscores - len(word)) * blank_char, end='\r', flush=True)
        # Reprint prefix and word to move cursor
        print(prefix + word, end="", flush=True)
    print()
    return word

print(get_input("Name: ", 20, '_'))

Handling IDLE

With IDLE, this fails. Thanks Python for giving us this... Anayway, if you want to handle running in IDLE, simply add the following at the top of the get_input() function:

    import sys

    if 'idlelib.run' in sys.modules:
        return input(prefix)

This will check if you are using IDLE and just prompt the user for input normally.

Update 1: Moved cursor to next char location

Update 2: Added Unix support

Update 2.1: Separated Original Windows only answer and Windows and Unix answer

Update 3: Handling IDLE




回答2:


Compose your prompt of text, a number of underscores, and then same number of backspace characters (\b).

n_underscores = 45
a = input('Enter your name:' + '_' * n_underscores + '\b' * n_underscores)
print('Hi,', a)



回答3:


You can use a \r character to return to the start of the line and overwrite text until you want the input cursor:

print("Enter your name: ____________________", end='\rEnter your name: ', flush=True)
a = input()

It is worth noting that moving a cursor only works in some consoles, for example, it will not work in IDLE, but it will work in windows command prompt



来源:https://stackoverflow.com/questions/61288221/move-the-cursor-back-for-taking-input-python

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!