让curses程序的输出在程序退出后仍能保留在终端滚动历史记录中

12

我对curses这个库还比较新,因此我正在尝试在Python中使用不同的方法。

我已经初始化了窗口并设置了窗口对象的scrollok属性。我可以添加字符串,并且滚动的效果使得addstr()不会在窗口末尾出现任何错误。

我希望能够在程序输出完成后,在我的终端程序(在本例中为tmux或KDE Konsole)中向后滚动。

在我的代码中,如果我跳过endwin()调用,我至少可以看到输出结果,但是此时需要进行一次reset调用才能重新启动终端。

另外,即使在程序运行时,当curses窗口向下滚动时,我也无法在Konsole中向上滚动以查看初始输出。

#!/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个回答

11

对于这个任务,我建议您使用一个pad(http://docs.python.org/2/library/curses.html#curses.newpad):

Pad类似于窗口,但它不受屏幕大小的限制,也不一定与屏幕的特定部分关联。[...] 只有窗口的一部分会在屏幕上显示出来。[...]

为了在使用curses后将pad的内容留在控制台上,我会从pad中读取内容,结束curses并将内容写入标准输出。

以下代码实现了您所描述的内容。

#!/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)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接