I would like to move a curses pad across the screen, but I can't figure out a way to automatically erase the pad from the previous position in the screen without erasing the contents of the pad. I don't want to have to redraw the pad every time I move it. Here's my test program:
import curses
import time
def main(stdscr):
pad = curses.newpad(10, 10)
ch = ord('A')
pad.addch(4, 4, ch)
for y in range(0, 10):
for x in range(0, 10):
print("adding pad at {y},{x}")
try:
pad.insch(y, x, ch)
except:
pass
if x % 9 == 0:
ch = 1
pad.refresh(0, 0, 0, 0, 10, 10)
time.sleep(2)
pad.refresh(0, 0, 1, 1, 11, 11)
time.sleep(2)
pad.refresh(0, 0, 2, 2, 12, 12)
time.sleep(2)
curses.wrapper(main)
At the end of this script, the window looks like:
AAAAAAAAAA
BAAAAAAAAAA
CBAAAAAAAAAA
DCBBBBBBBBBB
EDCCCCCCCCCC
FEDDDDDDDDDD
GFEEEEEEEEEE
HGFFFFFFFFFF
IHGGGGGGGGGG
JIHHHHHHHHHH
JIIIIIIIIII
JJJJJJJJJJ
The first two lines and the first two characters of each line are leftover from previous pad displays. I want these erased.
I can create a different pad with the same dimensions and use it to erase the block from the screen:
def main(stdscr):
pad = curses.newpad(10, 10)
erasepad = curses.newpad(10, 10)
ch = ord('A')
pad.addch(4, 4, ch)
for y in range(0, 10):
for x in range(0, 10):
print("adding pad at {y},{x}")
try:
pad.insch(y, x, ch)
except:
pass
if x % 9 == 0:
ch = 1
pad.refresh(0, 0, 0, 0, 10, 10)
time.sleep(2)
erasepad.refresh(0, 0, 0, 0, 10, 10)
pad.refresh(0, 0, 1, 1, 11, 11)
time.sleep(2)
erasepad.refresh(0, 0, 1, 1, 11, 11)
pad.refresh(0, 0, 2, 2, 12, 12)
time.sleep(2)
That's workable for my application, but is there a more efficient way? This requires me to create two pads for every animation block, and to completely erase every pad every time.
CodePudding user response:
That's roughly the case. The sample code is inefficient however, doing extra repainting. Take a look at noutrefresh
and doupdate
(to replace those refresh calls), and replace the time.sleep
with napms
(again, to improve performance).