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

Rob picture Rob · Aug 27, 2015 · Viewed 7.9k times · Source

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
    

Answer

Robᵩ picture Robᵩ · Aug 27, 2015

What is the reason for that?

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

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

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

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 = stdscr.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
    stdscr = curses.initscr()
    curses.cbreak()
    curses.noecho()
    stdscr.keypad(1)

    # Silly program to write to the screen,
    # wait for either <ENTER> or <Q>.
    # On <ENTER>, mess with the screen.
    # On <Q>, exit.
    stdscr.addstr(0, 0, ipsum)
    stdscr.move(0, 0)
    stdscr.refresh()
    i = 0
    j = 0

    while 1:
        c = stdscr.getch()
        if c == ord('q'):
            exit(0)
        if c == curses.KEY_ENTER or c == 10 or c == 13:
            i += 1
            if i % 3 == 0:
                stdscr.addstr(0, 0, ipsum.lower())
            if i % 3 == 1:
                stdscr.addstr(0, 0, ipsum.upper())
            if i % 3 == 2:
                stdscr.addstr(0, 0, ipsum)
            stdscr.move(0, 0)
        if c == curses.KEY_DOWN:
            y, x = stdscr.getyx()
            maxy, maxx = stdscr.getmaxyx()
            stdscr.move((y+1) % maxy, x)
        stdscr.refresh()


finally:
    # Standard shutdown. Probably don't need to change this.
    curses.nocbreak()
    stdscr.keypad(0)
    curses.echo()
    curses.endwin()

Reference: