2

I am creating a login panel in the terminal in python and I want to dynamically change icon before input i.e whenever the user fills the input the icon changes.

Example:

F:\command_line>python main.py
?  username: # initially there is a question mark.

✓ username: # If the user fills the username the icon changes to ✓

I tried:

default = '?'
onChange = '✓'
inp = input(default + " " + name + ":")
# I can't figure out how I can change it

Is it possible to do this? If so, How can I achieve it?

Zodiac
  • 121
  • 1
  • 9
  • 2
    Does this answer your question? [How do programs overwrite previous lines of output?](https://stackoverflow.com/questions/18287633/how-do-programs-overwrite-previous-lines-of-output) – Pranav Hosangadi Aug 26 '20 at 15:26
  • does it change on enter, or when the user types any key? – M Z Aug 26 '20 at 15:27
  • no, it didn't @PranavHosangadi – Zodiac Aug 26 '20 at 17:18
  • change on enter. @MZ – Zodiac Aug 26 '20 at 17:19
  • @Zodiac, that question gives a standard way to deal with terminals. You need to use that library to do what you want. In your programming career, you won't find the exact code that you need online, this seems to be one of those times. Alternatively, this will definitely answer your question. https://stackoverflow.com/a/11474509/843953 – Pranav Hosangadi Aug 26 '20 at 19:08

1 Answers1

1

I won't walk you through the entire thing but the link that @PranavHosangadi provided is a good resource.

It seems like you're using Windows so the curses module isn't immediately available to you. However you can pip install windows-curses to get most of the functionality. Although I have noticed some of the constants like curses.KEY_BACKSPACE differ on the windows version but you can fiddle with it and determine what works for you.

# The module you'll use
import curses

# this is the char value that backspace returns on windows
BACKSPACE = 8

# our main function
def main(stdscr):
    # this is just to initialize the input position
    inp = '? Username:'
    stdscr.addstr(1, 1, inp)
    
    # The input from the user will be assigned to 
    # this variable
    current = ''
    # our main method of obtaining user input
    # it essentially returns control after the 
    # user inputs a character
    # the return value is essentially what ord(char) returns
    # to get the actual character you can use chr(char)
    k = stdscr.getch()

    # break the loop when the x key is pressed
    while chr(k) != 'x':
        # remove characters for backspace presses
        if k == BACKSPACE:
            if len(current):
                current = current[:len(current) - 1]
        # only allow a max of 8 characters
        elif len(current) < 8:
            current = current + chr(k)
        
        # when 8 characters are entered, change the sign
        if len(current) == 8:
            inp = '✓ Username:'
        else:
            inp = '? Username:'
        
        # not clearing the screen leaves old characters in place
        stdscr.clear()
        # this enters the input on row 1, column 1
        stdscr.addstr(1, 1, inp + current)
        
        # get the next user input character
        k = stdscr.getch()

if __name__ == '__main__':
    # our function needs to be driven by curses.wrapper
    curses.wrapper(main)

Some resources:

Official Docs

Some helpful examples This one has some linux-only pieces, but with some trial and error, those parts are apparent.

Axe319
  • 4,255
  • 3
  • 15
  • 31