2013-05-26 23 views
1

下面的代码让您可以使用箭头键将“。”放在屏幕上的小网格中。你在哪里探索过或在旁边。即使我在第一次getch之前进行了刷新(要获得按键笔画),但在屏幕移出起始位置之前,屏幕不会显示任何内容。不应该在刷新后马上显示getstr,然后getch会在那之后等待?我甚至尝试添加stdscr.refresh(),但这也没有帮助。如何在等待第一个键击之前立即刷新屏幕?Python ncurses:直到第一次按键时才显示屏幕,即使刷新是第一次

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

文档已损坏。我当天使用了curses,但是libncurses对我来说是新的。

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

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

但随后refresh(3)了决定性避重就轻:先调用wnoutrefresh,

例行wrefresh作品,其拷贝命名为窗口,以虚拟屏幕,然后调用doupdate,其中虚拟屏幕比作物理屏幕并进行实际更新。 ...上面的“将命名窗口复制到虚拟屏幕”这个短语是不明确的。实际发生的情况是窗口中所有被触摸(改变)的线都被复制到虚拟屏幕上。这会影响使用重叠窗口的程序;这意味着如果两个窗口重叠,则可以按照的任一顺序刷新它们,并且仅当明确更改重叠区域时才会修改它们。 [重点煤矿]

这促使我来试试你的pad.refresh()其工作后加入

stdscr.refresh() 

。然后我将它进一步向上移动start()以查看它是否真的需要在每个打击垫上进行修改。我把它一路攀升到第一点是有stdscr与高产的工作:

def start(stdscr): 
    stdscr.refresh() 
    curses.curs_set(0) 
    … 

这意味巫术编程,但我不会看一个20岁的内脏图书馆是为了应付玻璃ttys而努力的。

+0

比我自己的回答更彻底,也帮助我理解它为什么会这样。谢谢! – Dan

0

当使用垫,出于某种原因,我不知道为什么,你必须调用后致电curses.doupdate垫的refresh

+0

可悲的是没有为我工作。文档http://docs.python.org/2/library/curses.html表示刷新是“简单noutrefresh()后跟doupdate()”。我尝试了movement.noutrefresh(),movement.refresh(),stdscr.noutrefresh(),stdscr.refresh(),curses.doupdate(),甚至尝试了所有这些,直到我点击关键。 – Dan

2

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

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

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

+0

+1哦,你打了我几个小时。没关系。 >< – msw

相关问题