How to set up a debug session for a curses console program

130 views
Skip to first unread message

pjfa...@yahoo.com

unread,
Feb 6, 2021, 3:06:09 PM2/6/21
to PyScripter
I have installed the portable PyScripter zip into C:\PyScripter and added that directory to my PATH.  When I try to use PyScripter to debug (F9) a python script that uses the python curses library (pip install windows-curses has been done, version 2.2.0), I get a popup Error box with only an Abort button that says:

Remote server is not connected.
Please reinitialize or disconnect the remote interpreter.

What steps do I need to take to debug a python curses program please?

TIA for any assistance you can offer.

Peter

pjfa...@yahoo.com

unread,
Feb 6, 2021, 3:18:37 PM2/6/21
to PyScripter
I forgot to add my environment: Win10-64 2004, Python 3.8.5.

PyScripter

unread,
Feb 6, 2021, 7:40:02 PM2/6/21
to PyScripter
I am afraid the curses module does not play well with PyScripter.

pjfa...@yahoo.com

unread,
Feb 6, 2021, 11:33:01 PM2/6/21
to PyScripter
Thanks for your response.

Is it possible to debug a curses script running in a separate console window on the same system?  Or is it something specific about any script using curses that means PyScripter cannot debug it?

I really need to be able to debug a set of scripts during development and testing where curses is fundamental to the application functionality.  If PyScripter is not the right tool to use, can you recommend one that will help in such an effort?

Peter

PyScripter

unread,
Feb 7, 2021, 7:59:16 PM2/7/21
to PyScripter
The curses module is not available in Windows by default (you need a separate installation for this) and in any case I do not know much about this module, so I am afraid I cannot help with your question.

pjfa...@yahoo.com

unread,
Feb 11, 2021, 1:03:01 AM2/11/21
to PyScripter
Python curses functionality is available for Windows by the simple expedient of "pip install windows-curses"; no other setup or installs are needed.  It works just fine for all of the functions I have tested so far.  Under the covers it uses the PDCurses library.

I will paste a very simple, low-function curses script below so you could test it for yourself if you find the time.

I will be interested if you can find out how to allow PyScripter debug a python script using curses functions, probably only by running a "remote" script in a separate terminal or console window on the same system.  I really liked the look of PyScripter and am sad that I cannot use it for debugging the task I have at hand.

Peter

pycurses.py:
------------------------cut here--------------------------------
import sys,os
import curses

def draw_menu(stdscr):
    k = 0
    cursor_x = 0
    cursor_y = 0

    # Clear and refresh the screen for a blank canvas
    stdscr.clear()
    stdscr.refresh()

    # Start colors in curses
    curses.start_color()
    curses.init_pair(1, curses.COLOR_CYAN, curses.COLOR_BLACK)
    curses.init_pair(2, curses.COLOR_RED, curses.COLOR_BLACK)
    curses.init_pair(3, curses.COLOR_BLACK, curses.COLOR_WHITE)

    # Loop where k is the last character pressed
    while (k != ord('q')):

        # Initialization
        #stdscr.clear()
        height, width = stdscr.getmaxyx()

        if k == curses.KEY_DOWN:
            cursor_y = cursor_y + 1
        elif k == curses.KEY_UP:
            cursor_y = cursor_y - 1
        elif k == curses.KEY_RIGHT:
            cursor_x = cursor_x + 1
        elif k == curses.KEY_LEFT:
            cursor_x = cursor_x - 1

        cursor_x = max(0, cursor_x)
        cursor_x = min(width-1, cursor_x)

        cursor_y = max(0, cursor_y)
        cursor_y = min(height-1, cursor_y)

        # Declaration of strings
        title = "Curses example"[:width-1]
        subtitle = "Written by Clay McLeod"[:width-1]
        keystr = "Last key pressed: {}".format(k)[:width-1]
        statusbarstr = "Press 'q' to exit | STATUS BAR | Pos: {}, {}".format(cursor_x, cursor_y)
        if k == 0:
            keystr = "No key press detected..."[:width-1]

        # Centering calculations
        start_x_title = int((width // 2) - (len(title) // 2) - len(title) % 2)
        start_x_subtitle = int((width // 2) - (len(subtitle) // 2) - len(subtitle) % 2)
        start_x_keystr = int((width // 2) - (len(keystr) // 2) - len(keystr) % 2)
        start_y = int((height // 2) - 2)

        # Rendering some text
        whstr = "Width: {}, Height: {}".format(width, height)
        stdscr.addstr(0, 0, whstr, curses.color_pair(1))

        # Render status bar
        stdscr.attron(curses.color_pair(3))
        stdscr.addstr(height-1, 0, statusbarstr)
        stdscr.addstr(height-1, len(statusbarstr), " " * (width - len(statusbarstr) - 1))
        stdscr.attroff(curses.color_pair(3))

        # Turning on attributes for title
        stdscr.attron(curses.color_pair(2))
        stdscr.attron(curses.A_BOLD)

        # Rendering title
        stdscr.addstr(start_y, start_x_title, title)

        # Turning off attributes for title
        stdscr.attroff(curses.color_pair(2))
        stdscr.attroff(curses.A_BOLD)

        # Print rest of text
        stdscr.addstr(start_y + 1, start_x_subtitle, subtitle)
        stdscr.addstr(start_y + 3, (width // 2) - 2, '-' * 4)
        stdscr.addstr(start_y + 5, start_x_keystr, keystr)
        stdscr.move(cursor_y, cursor_x)

        # Refresh the screen
        stdscr.refresh()

        # Wait for next input
        k = stdscr.getch()

def main():
    curses.wrapper(draw_menu)

if __name__ == "__main__":
    main()

------------------------cut here--------------------------------
Reply all
Reply to author
Forward
0 new messages