Make curses program output persist in terminal scrollback history after program exits

二次信任 提交于 2021-02-18 05:38:21

问题


I'm quite new to curses, so I'm trying out some different things in python.

I've initialized the window and set scrollok for the window object. I can add strings, and the scrolling works so that addstr() doesn't have any errors at the end of the window.

What I'd like to have is the ability to scroll back in the program output in my terminal program (tmux or KDE Konsole, in this case) after the program has finished.

In my code, I can at least see the output if I skip the endwin() call, but then the terminal needs a reset call to get back to operational.

Also, even while the program is running, after the curses window has scrolled down, I can't scroll back in Konsole to see the initial output.

#!/usr/bin/env python2
import curses
import time
win = curses.initscr()
win.scrollok(True)
(h,w)=win.getmaxyx()
h = h + 10
while h > 0:
    win.addstr("[h=%d] This is a sample string.  After 1 second, it will be lost\n" % h)
    h = h - 1
    win.refresh()
    time.sleep(0.05)
time.sleep(1.0)
curses.endwin()

回答1:


For this task, I would suggest that you use a pad (http://docs.python.org/2/library/curses.html#curses.newpad):

A pad is like a window, except that it is not restricted by the screen size, and is not necessarily associated with a particular part of the screen. [...] only a part of the window will be on the screen at one time. [...]

In order to leave the contents of the pad on the console after you have finished using curses, I would read the contents back in from the pad, end curses and write the contents to the standard output.

The following code achieves what you describe.

#!/usr/bin/env python2

import curses
import time

# Create curses screen
scr = curses.initscr()
scr.keypad(True)
scr.refresh()
curses.noecho()

# Get screen width/height
height,width = scr.getmaxyx()

# Create a curses pad (pad size is height + 10)
mypad_height = height + 10
mypad = curses.newpad(mypad_height, width);
mypad.scrollok(True)
mypad_pos = 0
mypad_refresh = lambda: mypad.refresh(mypad_pos, 0, 0, 0, height-1, width)
mypad_refresh()

# Fill the window with text (note that 5 lines are lost forever)
for i in range(0, height + 15):
    mypad.addstr("{0} This is a sample string...\n".format(i))
    if i > height: mypad_pos = min(i - height, mypad_height - height)
    mypad_refresh()
    time.sleep(0.05)

# Wait for user to scroll or quit
running = True
while running:
    ch = scr.getch()
    if ch == curses.KEY_DOWN and mypad_pos < mypad_height - height:
        mypad_pos += 1
        mypad_refresh()
    elif ch == curses.KEY_UP and mypad_pos > 0:
        mypad_pos -= 1
        mypad_refresh()
    elif ch < 256 and chr(ch) == 'q':
        running = False

# Store the current contents of pad
mypad_contents = []
for i in range(0, mypad_height):
    mypad_contents.append(mypad.instr(i, 0))

# End curses
curses.endwin()

# Write the old contents of pad to console
print '\n'.join(mypad_contents)


来源:https://stackoverflow.com/questions/14446311/make-curses-program-output-persist-in-terminal-scrollback-history-after-program

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!