Skip to content Skip to sidebar Skip to footer

Python Ncurses: Doesn't Show Screen Until First Key-press, Even Though Refresh Is First

The code below lets you walk around a small grid on the screen using the arrow keys putting '.' where you've explored or been next to. Even though I have my refresh before the fir

Solution 1:

The docs are broken. I'd used curses back in the day, but libncurses is new to me.

My first hint came from ncurses(3):

The ncurses library permits manipulation of data structures, called windows, which can be thought of as two-dimensional arrays of characters representing all or part of a CRT screen. A default window called stdscr, which is the size of the terminal screen, is supplied. Others may be created with newwin. … Special windows called pads may also be manipulated. These are windows which are not constrained to the size of the screen and whose contents need not be completely displayed.

But then refresh(3) got decidedly evasive:

The routine wrefresh works by first calling wnoutrefresh, which copies the named window to the virtual screen, and then calling doupdate, which compares the virtual screen to the physical screen and does the actual update. … The phrase "copies the named window to the virtual screen" above is ambiguous. What actually happens is that all touched (changed) lines in the window are copied to the virtual screen. This affects programs that use overlapping windows; it means that if two windows overlap, you can refresh them in either order and the overlap region will be modified only when it is explicitly changed. [emphasis mine]

which prompted me to try adding

stdscr.refresh()

after your pad.refresh() which worked. And then I moved it further up start() to see if it was really needed on every pad modification. I moved it all the way up to the first point there is a stdscr to work with yielding:

def start(stdscr):
    stdscr.refresh()
    curses.curs_set(0)
    …

which smacks of voodoo programming, but I'm not going to look at the innards of a 20-year old library made to cope with glass ttys to try to grok it.


Solution 2:

Add stdscr.refresh() sometime before the movement.refresh() to solve the issue.

By adding time.sleep(1) after the refresh statement, it does write to the screen, but then it disappears when stdscr.getch() is called, but only the first time. Probably has to do with some sort of delayed initialization of stdscr.

Calling stdscr.refresh() after the movement.refresh() has the same effect: The very first time through the loop stdscr.refresh() clears the screen, but not in subsequent times through the loop. By calling stdscr.refresh() early in the program it gets this weird first time refresh out of the way.


Solution 3:

When using a pad, for some reason—I don't know why—you have to call curses.doupdate after invoking the pad's refresh.


Solution 4:

Adding window.nodelay(1) before while solved issue for me.


Post a Comment for "Python Ncurses: Doesn't Show Screen Until First Key-press, Even Though Refresh Is First"