Reputation: 15
I am building a simple scrollable menu in Python 2.7 with curses and trying to make it scale for any window size, including if the terminal size changes (i.e. I want it to be larger or smaller while I'm using the menu). I have a simple test code that I'm using to try and figure out this problem. It seems, if this is possible, I am really close, but what I am seeing is that when I resize my terminal window (using mRemoteNG), the border draws lines to fill in space, as seen at the bottom of the screenshot, after I extended the window vertically:
The code I am using to test this is as follows:
import curses
import os
VERSION = "0.1-dev" #version number
screen = curses.initscr() #initialize the curses window
#Configure color pairs for showing select menu options as highlighted
curses.start_color() #enable color for highlighting menu options
curses.init_pair(1, curses.COLOR_BLACK, curses.COLOR_WHITE) #color pair 1
highlightText = curses.color_pair(1) #color pair for highlighted menu option
normalText = curses.A_NORMAL #color pair for non-highlighted menu options
#Configure global variables for Curses
curses.noecho() #disable the keypress echo to prevent double input
curses.cbreak() #disable line buffers to run the keypress immediately
curses.curs_set(0)
screen.keypad(1) #enable keyboard use
screen.addstr(2, 2, "Screen Resize Test" + VERSION, curses.A_UNDERLINE)
#test screen resize
def main_screen():
escape = False
while escape == False:
maxY, maxX = screen.getmaxyx()
screen.border('|', '|', '-', '-', '+', '+', '+', '+')
screen.addstr(4, 2, "MaxY: " + str(maxY))
screen.addstr(5, 2, "MaxX: " + str(maxX))
screen.refresh()
x = screen.getch()
if x == ord("q"):
escape = True
main_screen()
curses.endwin() # *** CRITICAL *** this closes the curses menu and returns user to bash
os.system('clear') #clears the screen to avoid curses remnants
I've tried many different placements of screen.refresh()
and screen.clear()
, but it never seems to get rid of the remnants of lines at the edges of the curses window. Obviously, if this is possible, I either can't figure out where to place one/both of these or I'm not on the right track.
Upvotes: 1
Views: 7927
Reputation: 54495
In your program, you should check for curses.KEY_RESIZE as a return value from getch
, and in that case, call screen.erase
.
Also, the existing call to screen.refresh
is unnecessary, since screen.getch
does that anyway.
This works for me:
import curses
import os
VERSION = "0.1-dev" #version number
screen = curses.initscr() #initialize the curses window
#Configure color pairs for showing select menu options as highlighted
curses.start_color() #enable color for highlighting menu options
curses.init_pair(1, curses.COLOR_BLACK, curses.COLOR_WHITE) #color pair 1
highlightText = curses.color_pair(1) #color pair for highlighted menu option
normalText = curses.A_NORMAL #color pair for non-highlighted menu options
#Configure global variables for Curses
curses.noecho() #disable the keypress echo to prevent double input
curses.cbreak() #disable line buffers to run the keypress immediately
curses.curs_set(0)
screen.keypad(1) #enable keyboard use
screen.addstr(2, 2, "Screen Resize Test" + VERSION, curses.A_UNDERLINE)
#test screen resize
def main_screen():
escape = False
while escape == False:
maxY, maxX = screen.getmaxyx()
screen.border('|', '|', '-', '-', '+', '+', '+', '+')
screen.addstr(4, 2, "MaxY: " + str(maxY))
screen.addstr(5, 2, "MaxX: " + str(maxX))
x = screen.getch()
if x == ord("q"):
escape = True
curses.endwin()
elif x == curses.KEY_RESIZE:
screen.erase()
screen.addstr(2, 2, "Screen Resize Test" + VERSION, curses.A_UNDERLINE)
main_screen()
Upvotes: 3