0

I'm trying to learn how to use Python Curses (and hopefully build a simple game), but somehow I cannot get curses panels to work.

Specifically, when I try to update_panels(), my script (below) immediately exits directly back to the prompt.

import curses, curses.panel, time as t

def main(stdscr):
    # Initialize some colors and styles
    curses.start_color()
    curses.init_pair( 1, curses.COLOR_RED, curses.COLOR_BLACK )
    pl_style = curses.color_pair( 1 ) + curses.A_BOLD + curses.A_REVERSE

    # Create a Background window and panel
    bg_W = curses.newwin( 10, 100, 5, 5 )
    bg_W.box(); 
    bg_W.addstr( 1, 2, "BG Window" )
    bg_P = curses.panel.new_panel( bg_W )
    bg_W.refresh(); t.sleep( 2 )

    # Create a Player window and panel
    pl_W = curses.newwin( 1, 1, 10, 20 )
    pl_W.insch( '+', pl_style )
    pl_P = curses.panel.new_panel( pl_W )
    pl_W.refresh(); t.sleep( 2 )

    # Update panels
    curses.panel.update_panels()
    curses.doupdate()

    # # Move the Player panel and update panels
    # pl_P.move( 10, 30 )
    # curses.panel.update_panels()
    # curses.doupdate()
    # t.sleep( 2 )

    while True: 
        if pl_W.getch() == 27: break

if __name__ == "__main__": 
    curses.wrapper( main )

Alternatively, when I try to just move panels, my script (below), returns an error.

import curses, curses.panel, time as t

def main(stdscr):
    # Initialize some colors and styles
    curses.start_color()
    curses.init_pair( 1, curses.COLOR_RED, curses.COLOR_BLACK )
    pl_style = curses.color_pair( 1 ) + curses.A_BOLD + curses.A_REVERSE

    # Create a Background window and panel
    bg_W = curses.newwin( 10, 100, 5, 5 )
    bg_W.box(); 
    bg_W.addstr( 1, 2, "BG Window" )
    bg_P = curses.panel.new_panel( bg_W )
    bg_W.refresh(); t.sleep( 2 )

    # Create a Player window and panel
    pl_W = curses.newwin( 1, 1, 10, 20 )
    pl_W.insch( '+', pl_style )
    pl_P = curses.panel.new_panel( pl_W )
    pl_W.refresh(); t.sleep( 2 )

    # # Update panels
    # curses.panel.update_panels()
    # curses.doupdate()

    # Move the Player panel and update panels
    pl_P.move( 10, 30 )
    curses.panel.update_panels()
    curses.doupdate()
    t.sleep( 2 )

    while True: 
        if pl_W.getch() == 27: break

if __name__ == "__main__": 
    curses.wrapper( main )

The error I get is as follows:

Traceback (most recent call last):
  File "panl2.py", line 36, in <module>
    curses.wrapper( main )
  File "C:\Program Files\Python38\lib\curses\__init__.py", line 105, in wrapper
    return func(stdscr, *args, **kwds)
  File "panl2.py", line 27, in main
    pl_P.move( 10, 30 )
_curses_panel.error: move_panel() returned ERR

I've had a hell of a time trying to figure out what is wrong, but am getting absolutely nowhere, and would be very grateful for any guidance.

I'm using windows-curses (v2.1.0) with Python 3.8 (v3.8.1:1b293b6) in the standard Windows command prompt (v10.0.18362.449) on an x64 Windows 10 Pro (v10.0.18362) machine.

Thomas Dickey
  • 51,086
  • 7
  • 70
  • 105
abmx
  • 1

1 Answers1

0

ncurses' move_panel function returns the result from mvwin, which is documented as follows:

Calling mvwin moves the window so that the upper left-hand corner is at position (x, y). If the move would cause the window to be off the screen, it is an error and the window is not moved. Moving subwindows is allowed, but should be avoided.

In python, you'd have to use a try/except block to avoid simply exiting when there is an error-return from ncurses.

Using "windows-curses", the underlying library is probably PDCurses (which has no documentation aside from comments in the source-code). However, its panel-support ultimately came from the same (Warren Tucker) implementation. You can see the error-returns in the source-code.

For what it's worth, the original panel library (author unknown) that one might have encountered in a vendor Unix machine (such as Solaris) did the same thing (see source on Illumos-gate), but the documentation provided could not have been useful when Tucker developed a clone (see "documentation").

Thomas Dickey
  • 51,086
  • 7
  • 70
  • 105