9

我有以下代码,可让您上下滚动一段文本。每次滚动(即处理用户输入)时,pad 都会按预期更新。但是,在按下第一个键之前没有显示任何内容,尽管我正在调用 pad.refresh() 就像我在每次用户输入后所做的那样。

我的代码如下所示:

def main(self,stdscr):

    x,y = 20,150 # size of the window
    u,a = 10,20 # where to place window - up,across
    pad = curses.newpad(20,150) # nlines, ncols
    pad_pos = 0
    exit = False

    pad.addstr(0,0,str(self.all_results))

    while not exit:
        pad.addstr(0,0,str(self.format_results()))
        ++ stdscr.refresh()
        pad.refresh(pad_pos,10, u,a, x,y)

        -- cmd = stdscr.getch()
        ++ cmd = pad.getch()

        stdscr.nodelay(1)

        + pad.getch() - caused the screen not to update
        + stdscr.refresh() - no change

        if cmd != -1:
            + pad.getch() - - caused the screen not to update
            if  cmd == curses.KEY_DOWN:
                if pad_pos < 3:
                    pad_pos += 1
                try:
                    pad.refresh(pad_pos,0, u,a, x,y)
                except curses.error:
                    pass
            elif cmd == curses.KEY_UP:
                if pad_pos != 0:
                    pad_pos -= 1
                try:
                    pad.refresh(pad_pos,0, u,a, x,y)
                except curses.error:
                    pass

编辑:代码中显示的更改已尝试的内容(+、++、--)

4

3 回答 3

11

stdscr.refresh()在一切按预期工作之前,似乎有必要(AFAIK 未记录)刷新 stdscr 一次,即 call 。我将其合并到您的示例中(我以前必须进行工作 - 见下文):

import curses

def main(stdscr):
    stdscr.keypad(True)
    stdscr.refresh() # This is the necessary initial refresh

    heigth, width = 20, 150 # size of the pad
    top, left = 10, 20 # where to place pad
    viewportHeight = 10
    scrollOffset = 0

    # generate a string to fill pad
    string = ''.join(chr(ord('a') + (x % 26)) for x in range(heigth*width-1))

    pad = curses.newpad(heigth, width)
    pad.addstr(string)
    pad.refresh(scrollOffset, 0, top, left, top + 10, left + width)

    cmd = stdscr.getch()
    while True:
        if  cmd == curses.KEY_DOWN and scrollOffset < heigth - viewportHeight - 1:
            scrollOffset += 1
        elif cmd == curses.KEY_UP and scrollOffset > 0:
            scrollOffset -= 1
        if cmd:
            pad.refresh(scrollOffset, 0, top, left, top + 10, left + width)
        cmd = stdscr.getch()

curses.wrapper(main)

我希望这能解决你的问题!

几点说明:

  • 对于将来,我建议您使用curses.wrapper(main)-function 设置 curses 环境并使用as 参数调用您的main(stdscr)方法。stdscr它还注意适当地拆除诅咒,如果您的代码出现问题,这可以防止终端损坏。也许您想查看Kuchling 和 Raymond关于如何使用 python curses 包的有用教程。

  • 请提供一个可重现的例子。您的包含变量,例如self.all_result我必须在哪里进行猜测才能理解您的问题。事实上,我花了更多时间弄清楚您的代码试图准确实现什么并重现您描述的错误行为,而不是找到实际的解决方案。

如果您编辑您的问题以将其归结为实际问题 - 我认为这对许多使用 Python 的 curses 模块的人可能非常有帮助。

谢谢和快乐的黑客;)

编辑:我刚刚意识到您为来自官方来源的响应图提供了赏金,因此我进行了更多挖掘,并在 SO 上找到了等效响应,这也表明,这 - 让我们称之为错误 - 到目前为止没有记录。对于进行一些 libncurses 研究的原因,我最好的猜测是,curses.wrapper在我的情况下,您手动,甚至 libnurses 本身在初始化期间的任何时候都调用了清除屏幕方法。因此,可能会设置清除标志,从而在第一次刷新时清除屏幕,而不是预期的行为。

于 2014-10-10T18:38:17.873 回答
2

stdscr.getch()导致隐式刷新stdscr(在此之前未更新),pad通过用空白覆盖它从屏幕上擦除stdscr。试试看pad.getch(),要不刷新stdscr前先pad.refresh()

于 2014-08-12T23:19:47.113 回答
0

stdscr.nodelay(1)在挂断之前尝试拨打电话stdscr.getch()

于 2014-10-10T16:03:29.093 回答