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

Python';在收到第一个字符之前,s curses模块不会刷新pad,python,curses,python-curses,Python,Curses,Python Curses,我有下面的代码,可以让你上下滚动一段文字。每次滚动(即处理用户输入)时,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(

我有下面的代码,可以让你上下滚动一段文字。每次滚动(即处理用户输入)时,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
def干管(自身、stdscr):
x、 y=20150#窗户尺寸
u、 a=10,20#在何处安装车窗,交叉
pad=诅咒。newpad(20150)#nlines,ncols
焊盘位置=0
退出=错误
pad.addstr(0,0,str(self.all_结果))
不退出时:
addstr(0,0,str(self.format_results()))
++stdscr.refresh()
焊盘刷新(焊盘位置,10,u,a,x,y)
--cmd=stdscr.getch()
++cmd=pad.getch()
stdscr.nodelay(1)
+pad.getch()-导致屏幕未更新
+stdscr.refresh()-无更改
如果cmd!=-1:
+pad.getch()-导致屏幕不更新
如果cmd==curses.KEY\u向下:
如果焊盘位置<3:
焊盘位置+=1
尝试:
键盘刷新(键盘位置,0,u,a,x,y)
除了curses.error:
通过
elif cmd==curses.KEY\u UP:
如果pad_位置!=0:
焊盘位置-=1
尝试:
键盘刷新(键盘位置,0,u,a,x,y)
除了curses.error:
通过

< >编辑:在已尝试的代码(+、++、->)/> > <代码> STDSCR.GGCHE()>代码>中发生的更改导致对代码< STDSCR (在此之前未更新)的隐式刷新,它通过空白(<代码> STDSCR )重写,从屏幕上擦除<代码> Pad < /代码>。在第一个
pad.refresh()

之前,尝试
pad.getch()
,或者刷新
stdscr
,尝试调用
stdscr.nodelay(1)
,然后再挂断
stdscr.getch()

似乎有必要(没有文档记录的)刷新stdscr一次,即调用
stdscr.refresh()
,在一切按预期进行之前。我将这一点纳入了您的示例中(我以前必须使其完全起作用-见下文):

导入诅咒
def干管(stdscr):
stdscr.键盘(正确)
stdscr.refresh()#这是必要的初始刷新
高度,宽度=20,150#衬垫尺寸
顶部,左侧=10,20#放置衬垫的位置
视口高度=10
scrollOffset=0
#生成一个字符串来填充pad
字符串=“”。在范围(高*宽-1)内为x连接(chr(ord('a')+(x%26))
pad=curses.newpad(高度、宽度)
pad.addstr(字符串)
刷新(滚动偏移量,0,顶部,左侧,顶部+10,左侧+宽度)
cmd=stdscr.getch()
尽管如此:
如果cmd==curses.KEY_向下并滚动偏移0:
滚动偏移量-=1
如果cmd:
刷新(滚动偏移量,0,顶部,左侧,顶部+10,左侧+宽度)
cmd=stdscr.getch()
curses.wrapper(主)
我希望这能解决你的问题

几句话:

  • 对于将来,我建议您使用
    curses.wrapper(main)
    -函数,该函数设置curses环境并调用
    main(stdscr)
    方法,参数为
    stdscr
    。它还注意适当地删除诅咒,这可以防止在代码出错时出现终端损坏。也许您想查看关于如何使用python curses包的有用信息

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

如果您编辑您的问题,将其归结为实际问题,我认为这对许多使用Python的诅咒模块的人非常有帮助

谢谢&happy hacking;)


编辑:我刚刚意识到你提供了一笔悬赏,以获得官方消息来源的回复,所以我再翻了一番,发现,这也表明,这个——我们称之为bug——到目前为止还没有记录在案。对于为什么要做一些libncurses研究,我的最佳猜测是
诅咒.wrapper
在我的情况下,您可以在初始化过程中的任何时候手动调用,甚至libncurses本身也可以调用。因此,可能会设置清除标志,从而在第一次刷新时清除屏幕,而不是预期的行为。

我尝试了这些建议,但仍然面临相同的问题。如果尝试了这些建议,则从上面编辑的代码中看不出。这些行不是在第一次调用
pad.refresh()
之前。另外,
pad.getch()
的预期用途是将
cmd=stdscr.getch()
替换为
cmd=pad.getch()
,而不仅仅是在调用了
stdscr.getch()
之后继续调用
pad.getch()
。我还添加了您提到的基于++的更改,但仍然没有乐趣。您可以随时根据您认为的代码外观更新您的答案:-)第一个答案不能解决问题吗?或者你错过了什么来接受它?我相信这将与一个不会不断变化的字符串一起工作。但是我使用的字符串在不断更新。在测试了所有这些之后,下面的答案解决了我的问题。不过,非常感谢您提供的所有信息,非常感谢。
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)