在我使用Curses的Python脚本中,我有一个分配了一些文本的subwin。因为文本长度可能比窗口大小更长,所以文本应该是可滚动的。
对于Curses窗口,似乎没有任何类似CSS-"overflow“的属性。Python/Curses文档在这方面也相当含糊。
在座的任何人都知道如何使用Python编写一个可滚动的Curses子窗口并实际滚动浏览它?
\编辑:更精确的问题
发布于 2010-03-26 19:55:43
好的,对于window.scroll
,移动窗口的内容太复杂了。相反,curses.newpad
是为我做的。
创建焊盘:
mypad = curses.newpad(40,60)
mypad_pos = 0
mypad.refresh(mypad_pos, 0, 5, 5, 10, 60)
然后,您可以根据cmd
中来自window.getch()
的输入,通过增加/减少mypad_pos
进行滚动
if cmd == curses.KEY_DOWN:
mypad_pos += 1
mypad.refresh(mypad_pos, 0, 5, 5, 10, 60)
elif cmd == curses.KEY_UP:
mypad_pos -= 1
mypad.refresh(mypad_pos, 0, 5, 5, 10, 60)
发布于 2010-03-25 21:23:21
设置window.scrollok(真)。
发布于 2016-01-03 14:25:45
我想用滚动板显示一些大文本文件的内容,但效果不好,因为文本可能会有换行,而且很难计算出一次要显示多少个字符来适应良好的列数和行数。
所以我决定首先将我的文本文件拆分成精确的列字符的行,当行太短时用空格填充。然后滚动文本就变得更容易了。
以下是显示任何文本文件的示例代码:
#!/usr/bin/python
# -*- coding: utf-8 -*-
import curses
import locale
import sys
def main(filename, filecontent, encoding="utf-8"):
try:
stdscr = curses.initscr()
curses.noecho()
curses.cbreak()
curses.curs_set(0)
stdscr.keypad(1)
rows, columns = stdscr.getmaxyx()
stdscr.border()
bottom_menu = u"(↓) Next line | (↑) Previous line | (→) Next page | (←) Previous page | (q) Quit".encode(encoding).center(columns - 4)
stdscr.addstr(rows - 1, 2, bottom_menu, curses.A_REVERSE)
out = stdscr.subwin(rows - 2, columns - 2, 1, 1)
out_rows, out_columns = out.getmaxyx()
out_rows -= 1
lines = map(lambda x: x + " " * (out_columns - len(x)), reduce(lambda x, y: x + y, [[x[i:i+out_columns] for i in xrange(0, len(x), out_columns)] for x in filecontent.expandtabs(4).splitlines()]))
stdscr.refresh()
line = 0
while 1:
top_menu = (u"Lines %d to %d of %d of %s" % (line + 1, min(len(lines), line + out_rows), len(lines), filename)).encode(encoding).center(columns - 4)
stdscr.addstr(0, 2, top_menu, curses.A_REVERSE)
out.addstr(0, 0, "".join(lines[line:line+out_rows]))
stdscr.refresh()
out.refresh()
c = stdscr.getch()
if c == ord("q"):
break
elif c == curses.KEY_DOWN:
if len(lines) - line > out_rows:
line += 1
elif c == curses.KEY_UP:
if line > 0:
line -= 1
elif c == curses.KEY_RIGHT:
if len(lines) - line >= 2 * out_rows:
line += out_rows
elif c == curses.KEY_LEFT:
if line >= out_rows:
line -= out_rows
finally:
curses.nocbreak(); stdscr.keypad(0); curses.echo(); curses.curs_set(1)
curses.endwin()
if __name__ == '__main__':
locale.setlocale(locale.LC_ALL, '')
encoding = locale.getpreferredencoding()
try:
filename = sys.argv[1]
except:
print "Usage: python %s FILENAME" % __file__
else:
try:
with open(filename) as f:
filecontent = f.read()
except:
print "Unable to open file %s" % filename
else:
main(filename, filecontent, encoding)
主要的技巧是这行代码:
lines = map(lambda x: x + " " * (out_columns - len(x)), reduce(lambda x, y: x + y, [[x[i:i+out_columns] for i in xrange(0, len(x), out_columns)] for x in filecontent.expandtabs(4).splitlines()]))
首先,将文本中的表格转换为空格,然后使用splitlines()方法将文本转换为行数组。但有些行可能比我们的列数更长,所以我将每行拆分为列字符块,然后使用reduce将结果列表转换为行列表。最后,我使用map用尾随空格填充每一行,这样它的长度就是列字符。
希望这能有所帮助。
https://stackoverflow.com/questions/2515244
复制相似问题