首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >如何在Python/Curses子窗口中滚动文本?

如何在Python/Curses子窗口中滚动文本?
EN

Stack Overflow用户
提问于 2010-03-25 20:04:54
回答 4查看 33.6K关注 0票数 26

在我使用Curses的Python脚本中,我有一个分配了一些文本的subwin。因为文本长度可能比窗口大小更长,所以文本应该是可滚动的。

对于Curses窗口,似乎没有任何类似CSS-"overflow“的属性。Python/Curses文档在这方面也相当含糊。

在座的任何人都知道如何使用Python编写一个可滚动的Curses子窗口并实际滚动浏览它?

\编辑:更精确的问题

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2010-03-26 19:55:43

好的,对于window.scroll,移动窗口的内容太复杂了。相反,curses.newpad是为我做的。

创建焊盘:

代码语言:javascript
复制
mypad = curses.newpad(40,60)
mypad_pos = 0
mypad.refresh(mypad_pos, 0, 5, 5, 10, 60)

然后,您可以根据cmd中来自window.getch()的输入,通过增加/减少mypad_pos进行滚动

代码语言:javascript
复制
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)
票数 32
EN

Stack Overflow用户

发布于 2010-03-25 21:23:21

设置window.scrollok(真)。

Documentation

票数 4
EN

Stack Overflow用户

发布于 2016-01-03 14:25:45

我想用滚动板显示一些大文本文件的内容,但效果不好,因为文本可能会有换行,而且很难计算出一次要显示多少个字符来适应良好的列数和行数。

所以我决定首先将我的文本文件拆分成精确的列字符的行,当行太短时用空格填充。然后滚动文本就变得更容易了。

以下是显示任何文本文件的示例代码:

代码语言:javascript
复制
#!/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)

主要的技巧是这行代码:

代码语言:javascript
复制
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用尾随空格填充每一行,这样它的长度就是列字符。

希望这能有所帮助。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/2515244

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档