Python ncurses:在第一次按键之前不显示屏幕,即使刷新是第一次

时间:2013-05-26 21:08:04

标签: python ncurses python-curses

下面的代码可让您使用箭头键“。”在屏幕上的小网格中走动。你在哪里探索过或在旁边。即使我在第一次getch之前刷新(获得一个击键),屏幕也不会先显示任何内容,直到你离开你的起始位置。不应该立即显示addstr然后刷新然后getch等待吗?我甚至尝试添加一个stdscr.refresh(),但这也没有帮助。如何在等待第一个击键之前立即刷新屏幕?

import curses

def start(stdscr):
    curses.curs_set(0)
    movement = curses.newpad(10, 10)

    cur_x, cur_y = 5, 5

    while True:
        movement.addstr(cur_y, cur_x, '@')
        for (x_off, y_off) in [(-1,0),(1,0),(0,-1),(0,1)]:
            movement.addstr(cur_y + y_off, cur_x + x_off, '.')
        movement.refresh(1, 1, 0, 0, 7, 7) #Nothing is displayed until after the first key-stroke

        key_stroke = stdscr.getch()
        move_attempt = False
        if 0 < key_stroke < 256:
            key_stroke = chr(key_stroke)
        elif key_stroke == curses.KEY_UP and cur_y > 1:
            cur_y -= 1
        elif key_stroke == curses.KEY_DOWN and cur_y < 8:
            cur_y += 1
        elif key_stroke == curses.KEY_LEFT and cur_x > 1:
            cur_x -= 1
        elif key_stroke == curses.KEY_RIGHT and cur_x < 8:
            cur_x += 1
        else:
            pass

if __name__ == '__main__':
    curses.wrapper(start)

4 个答案:

答案 0 :(得分:5)

文档被破坏了。我当天用过诅咒,但libncurses对我来说是新的。

我的第一个提示来自ncurses(3)

  

ncurses库允许操作称为窗口的数据结构,可以将其视为表示CRT屏幕全部或部分的二维字符数组。提供了一个名为stdscr的默认窗口,它是终端屏幕的大小。其他人可能会用newwin创建。   ...   也可以操纵称为垫的特殊窗口。这些窗口不受屏幕大小的限制,其内容不需要完全显示。

然后refresh(3)明显回避:

  

例程wrefresh通过首先调用wnoutrefresh来工作,它将命名窗口复制到虚拟屏幕,然后调用doupdate,它将虚拟屏幕与物理屏幕进行比较并进行实际更新。 ...上面的短语“将命名窗口复制到虚拟屏幕”是不明确的。实际发生的是窗口中所有触摸(更改)的行都被复制到虚拟屏幕。这会影响使用重叠窗口的程序;这意味着如果两个窗口重叠,您可以按任意顺序刷新它们,只有在显式更改重叠区域时才会修改重叠区域。 [强调我的]

促使我尝试添加

stdscr.refresh()
pad.refresh()工作之后

。然后我进一步向上移动start(),看看是否真的需要每次修改垫。我把它一直移动到第一点,有一个stdscr与屈服一起工作:

def start(stdscr):
    stdscr.refresh()
    curses.curs_set(0)
    …
有点像伏都教编程,但我不会去看一个20年历史的图书馆的内部,以应对玻璃ttys试图弄清楚。

答案 1 :(得分:2)

stdscr.refresh()之前的某个时间添加movement.refresh()以解决问题。

通过在刷新语句之后添加time.sleep(1),它会写入屏幕,但是当调用stdscr.getch()时它会消失,但只是第一次。可能与stdscr的某种延迟初始化有关。

stdscr.refresh()之后调用movement.refresh()具有相同的效果:第一次通过循环stdscr.refresh()清除屏幕,但不会在后续循环中清除。通过在程序的早期调用stdscr.refresh(),可以让这个奇怪的第一次刷新。

答案 2 :(得分:0)

使用打击垫时,出于某种原因 - 我不知道为什么 - 在调用打击垫的curses.doupdate之后你必须打电话给refresh

答案 3 :(得分:0)

window.nodelay(1) 之前添加 while 为我解决了问题。