I'm writing a curses UI program in Python. I am using the curses wrapper and getting a screen object as a parameter to a function I've set up.
I divide the screen up into some smaller windows using curses.newwin()
calls. I divide those windows up to separate the border from the content by calling.
inner_window_object = outer_window_object.subwin()
The issue is when I do a "self.log_win.getkey()" and use an arrow key, instead of the expected "KEY_UP" I get what looks like an escape sequence of three different key press events. If I do a "self.screen.getkey()" I get the expected key, however my display is now borked because screen gets refreshed (and overwrites my other windows).
game = MyProgram()
curses.wrapper(game.main)
class MyProgram:
def main(screen)
self.screen = screen
log_lines = 10
max_row, max_col = self.screen.getmaxyx()
self.stats_box = curses.newwin(max_row-log_lines, max_col, 0, 0)
self.stats_box.border()
self.stats_box.refresh()
self.stats_win = self.stats_box.subwin(max_row-log_lines-2, max_col-2, 1, 1)
self.stats_win.clear()
self.stats_win.refresh()
self.log_box = curses.newwin(log_lines, max_col, max_row - log_lines, 0)
self.log_box.border()
self.log_box.refresh()
self.log_win = self.log_box.subwin(log_lines-2, max_col-2, max_row - log_lines +1 ,1)
self.log_win.scrollok(True)
self.log_win.idlok(True)
self.log_win.clear()
self.log_win.refresh()
key = ""
while key != "Q":
self.display_some_stuff_in_stats_win()
self.stats_win.refresh()
self.log_some_stuff_to_log_win()
self.log_win.refresh()
key = self.log_win.getkey()
self.do_stuff_with_key(key)
Anyone know what's going on here? Shouldn't I be able to do getkey on a subwindow? Would it make a difference if I just did subwin off the screen object for everything?
I get the similar behavior using get_ch and get_wch.
python's curses binding initializes the top-level window stdscr
to enable "keypad" mode, but does not modify the behavior of underlying curses for subsequently created windows, which does not initialize "keypad" mode.
If you add
self.log_win.keypad(1)
after
self.log_win = self.log_box.subwin(log_lines-2, max_col-2, max_row - log_lines +1 ,1)
then it will do what you intend.