A simple way to print few line stuck to the same position

Hans Mulder hansmu at xs4all.nl
Sat Jun 4 19:00:57 EDT 2011


On 4/06/11 13:14:05, TheSaint wrote:
> Hans Mulder wrote:

>> A minimalist solution would be to print the labels ("This count", etc.)
>> only once, and position the cursor after it to update the report.

> Generally a good point. Similar sequences are working for coloring and
> formatting text.

As I said, VT100 sequences work in pretty much any modern terminal or
emulator (but not in a DOS box under Windows).

> I don't know whether the program would behave to someone
> else who using not konsole like I do.

If you use the "\033[H" sequence to move the cursor to a predefined
postition, you'll find that other people's windows have a different
size from yours.  The standard library provides thin wrappers around
the  low-level calls need to figure out the window size:

import array
import fcntl
import sys
import termios

def getwindowsize():
     buf = array.array('h', [0] * 4)
     res = fcntl.ioctl(sys.stdout, termios.TIOCGWINSZ, buf, True)
     return buf[0:2]

rows, columns = getwindowsize()

print rows, columns

Alternatively, you could parse the output of `stty -a`.

Oh, and people will resize their window while your script is running,
and expect it to respond sensibly.  You could install a handler for
SIGWINCH signals, but at this point curses will begin to look more
and more attractive, as it will handle these details for you.

But then, maybe you can avoid absolute coordinates altogether.  If
your report is always exactly six lines, you could write the sequence
"\r\033[5A" after each report.  This moves the cursor to the left
margin and five lines up, ready to overwrite the previous report,
independent of window size.

>> The module is called "curses" and, yes, it would be the best way to go.

> OK, I didn't understand if I must setup a window first in order to implement
> cursor positioning.

If you use curses, you must initialize it by calling curses.initscr(),
which returns a "WindowObject" representing the konsole window.  To
put things on the screen, you call methods on this object.  Keep in
mind that a "window" in curses jargon is just a rectangle inside
your konsole window.  You can't create real Windows using curses.

Whether or not you use curses, if the numbers in the current report can
be smaller than those in the previous report, you'll want to write some
spaces after each number to erase the previous number.  For example, if
you try to overwrite "this count: 10" with "this count: 9", you'll end
up with "this count: 90" on the screen.  You don't want that to happen.


Hope this helps,

-- HansM






More information about the Python-list mailing list