Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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
    
like image 654
Rob Avatar asked Mar 14 '23 23:03

Rob


1 Answers

  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:

  • http://pubs.opengroup.org/onlinepubs/007908799/cursesix.html
  • https://docs.python.org/2/howto/curses.html
  • ncurses- KEY_ENTER is fail
like image 142
Robᵩ Avatar answered Apr 01 '23 16:04

Robᵩ