Search code examples
pythoncursespython-curses

Interpreting "ENTER" keypress in stdscr (curses module in Python)


I am using Python's curses module. In stdscr, whenever I press enter key, curse moves to the first column in the same line. I have couple of questions regarding it.

  1. What is the reason for that?

  2. Is there a way to move the curse to the next line?

  3. If I want to do certain things (execute some function or something) on enter key press, then what will come in 'if' condition? e.g.

    if (condition which will determine if ENTER was pressed or not)
        # somecode
    

Solution

    1. What is the reason for that?

    You need to invoke curses.noecho() as part of your initialization.

    1. Is there a way to move the curse to the next line?

    screen.move(y,x) will move to an absolute location. screen.getyx() will tell you your current location.

    1. If I want to do certain things (execute some function or something) on enter key press, then what will come in 'if' condition? e.g.

    You'd think that you could call getch() and compare the result with KEY_ENTER. In practice, you need to check for more values than that. Depending upon your terminal settings, which library you use, and phase of the moon, you may need to check for newline (aka \n, ^J, ASCII 10) or carriage return (\r, ^M, ASCII 13).

    c = screen.getch()
    if c == curses.KEY_ENTER or c == 10 or c == 13:
        # I hit ENTER
    

    Sample program:

    import curses
    
    # Thanks, http://www.ipsum-generator.com
    ipsum = '''Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer
    nec odio. Praesent libero. Sed cursus ante dapibus diam. Sed nisi. Nulla
    quis sem at nibh elementum imperdiet. Duis sagittis ipsum. Praesent
    mauris. Fusce nec tellus sed augue semper porta. Mauris massa. Vestibulum
    lacinia arcu eget nulla. Class aptent taciti sociosqu ad litora torquent
    per conubia nostra, per inceptos himenaeos.'''
    
    try:
        # Standard startup. Probably don't need to change this
        screen = curses.initscr()
        curses.cbreak()
        curses.noecho()
        screen.keypad(True)
    
        # Silly program to write to the screen,
        # wait for either <ENTER> or <Q>.
        # On <ENTER>, mess with the screen.
        # On <Q>, exit.
        screen.addstr(0, 0, ipsum)
        screen.move(0, 0)
        screen.refresh()
        i = 0
        j = 0
    
        while True:
            c = screen.getch()
            if c == ord('q'):
                exit(0)
            if c == curses.KEY_ENTER or c == 10 or c == 13:
                i += 1
                if i % 3 == 0:
                    screen.addstr(0, 0, ipsum.lower())
                if i % 3 == 1:
                    screen.addstr(0, 0, ipsum.upper())
                if i % 3 == 2:
                    screen.addstr(0, 0, ipsum)
                screen.move(0, 0)
            if c == curses.KEY_DOWN:
                y, x = screen.getyx()
                maxy, maxx = screen.getmaxyx()
                screen.move((y+1) % maxy, x)
            screen.refresh()
    
    
    finally:
        # Standard shutdown. Probably don't need to change this.
        curses.nocbreak()
        screen.keypad(0)
        curses.echo()
        curses.endwin()
    

    Reference: