Python curses模块在收到第一个字符之前不会刷新pad

时间:2014-08-12 15:38:58

标签: python curses python-curses

我有以下代码,允许您向上和向下滚动文本。每次滚动(即处理用户输入)时,打击垫都会按预期更新。但是,在按下第一个键之前没有显示任何内容,尽管我正在调用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

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

3 个答案:

答案 0 :(得分:7)

在一切按预期工作之前,似乎有(AFAIK未记录的)刷新stdscr的必要性,即调用stdscr.refresh()。我把这个结合到你的例子中(我之前必须完成工作 - 见下文):

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) - 设置curses环境的功能,并使用main(stdscr)作为参数调用stdscr方法。它还需要适当地拆除curses,以防止在代码中出现问题时终端损坏。也许你想查看有关如何使用python curses包的有用的tutorial by Kuchling and Raymond

  • 请提供可重现的示例。你的代码包含self.all_result之类的变量,我必须猜测才能理解你的问题。事实上,我花了更多的时间弄清楚你的代码究竟想要实现什么,并重现你所描述的错误行为,而不是找到实际的解决方案。

如果您编辑问题以解决实际问题 - 我认为这对使用Python诅咒模块的许多人来说非常有帮助。

谢谢&amp;快乐的黑客;)

编辑:我刚刚意识到你从官方消息来源提供了回报,所以我再挖一点,发现an equivalent response on SO,这也表明,这个 - 让我们称它为bug - 到目前为止没有记录。我最好猜测做一些libncurses研究的原因是,在我的情况下curses.wrapper,你手动,甚至libnurses本身在初始化期间的任何时候称为clear screen method。因此,可以设置clear标志,从而在第一次刷新时清除屏幕而不是预期的行为。

答案 1 :(得分:2)

stdscr.getch()导致隐式刷新stdscr(之前未更新),通过使用空白pad覆盖屏幕上的stdscr。尝试pad.getch(),或者在第一个stdscr之前刷新pad.refresh()

答案 2 :(得分:0)

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