How to remove subtitle in python curses module

I have a curses application that uses subwindows, but I cannot remove them.

For example, this code does not work:

import curses def fill(window, ch): y, x = window.getmaxyx() s = ch * (x - 1) for line in range(y): window.addstr(line, 0, s) def main(stdscr): fill(stdscr, 'M') stdscr.refresh() stdscr.getch() subwin = stdscr.subwin(1, 28, 20, 13) fill(subwin, 'J') subwin.refresh() subwin.getch() del subwin stdscr.touchwin() stdscr.refresh() stdscr.getch() curses.wrapper(main) 

When you run this code, the screen is filled with "M", and then when you press the key, a subtitle is created and "J" is filled. Finally, when you press the key again, the code removes the subwindow and completely redraws the screen. However, these Js still exist.

After some experimentation, I found that calling the clear () method on stdscr would cause the header to be turned on, but I would like to restore the background as it is, without blanking it and rewriting it. Does anyone know how to do this?

+4
source share
2 answers

Is there a good reason why you use the subtitle? If you create a new top-level window, the code works correctly - just change stdscr.subwin to curses.newwin and it works as you expected.

I am not a curse expert, but I believe that subwindow shares its character buffer with its parent in such a way that changes to one will also affect the other. So, if you want to divide the window into logical areas (perhaps a menu bar, main area and status bar), then auxiliary windows are useful. If, however, you are looking for something more, like a dialog box or a pop-up menu, then an all-new window (with its own separate buffer) is what you need.

I cannot find the final link to ncurses that agrees or disagrees with me, but the man page for AIX seems to confirm this:

Recall that the subtitle has its parent window buffer. Changes made to the general window buffer in the area covered by the subtitle through the parent window or any of its subwindows affect all windows sharing the window buffer.

Of course, this is not final for ncurses, but I cannot find anything contrary, and it seems to explain the observed behavior. I also did a rough experiment, where right after the subwin.getch() in your example, I added this line:

 raise Exception(stdscr.instr(20, 15, 3)) 

In your example, I get JJJ as the contents of the actual main window. If I use curses.newwin() to create a window instead of stdscr.subwin() , I get the expected MMM .

I don’t know how many specific Python curse resources exist, but most of the standard ncurses tutorials and documents are very useful at this level. Back when I needed to do some work, this document was quite useful. If you go to the β€œExample” section, you will see that the menu popups are not windows - he refers to this with the following slightly vague explanation:

We do not want this new window to overwrite previously written characters in the background. They should stay there after closing the menu. This is why a menu window cannot be created as a substring of stdscr.

In addition, I remember that using both stdscr and your own windows can cause problems - the official introduction of ncurses has some warnings about this. He also suggests avoiding overlapping windows completely, as they seem to be error prone, but I don’t remember having any problems with them for short-term transient modal dialogs (this is the only use I made to them). Of course, just because my simple use case did not reveal any problems, this does not mean that they are not. However, in something as complex as ncurses, I see the wisdom in keeping things as simple as you can.

Hope some help. As I said, I am by no means an expert on curses, but I hope this is a few more steps forward.

+7
source

There are two problems with this code.

First, as the previous poster noted, subwindows shares a buffer with the parent window, so you should use curses.newwin() if you want a completely independent window.

Secondly, using del to remove a window is problematic because it relies on link collection / garbage collection to work properly. (First, you need to remove all window references in order for it to work.) I recommend using the curses.panel module to explicitly show / hide the window.

+1
source

All Articles