Skip to main content
 首页 » 编程设计

Python:两次调用 'curses' 会塞满我的终端

2025年05月04日10bonelee

我正在使用 curses 解决终端游戏中的谜题(Mac OSX,Python 2.6.5)。这个谜题涉及旋转一些转盘来打开锁。我的代码,有些简化(请原谅丑陋):

import curses 
 
dial = ["| -1  |","|-1/3 |","|  0  |","| 1/2 |","| 2/3 |","|  1  |"] 
 
clear = "       " 
pointer = "   ^   " 
subdials = [clear,clear] 
 
d = {'d0':{},'d1':{}} 
d['d0'] = {'val':2,'disp':dial[2]} 
d['d1'] = {'val':2,'disp':dial[2]} 
 
def spin(scr): 
    try: 
        curses.curs_set(0) 
    except: 
        pass 
 
    solved = 0 
    p = 0 
    subdials[p] = pointer 
    dials = [d['d0']['disp'],d['d1']['disp']] 
 
    maxy,maxx = scr.getmaxyx() 
 
    newscr = scr.subwin(10,51,maxy-15,0) 
    newscr.box(ord('|'),ord('-')) 
    newscr.addstr(4,8,''.join(dials)) 
    newscr.addstr(6,8,''.join(subdials)) 
    newscr.refresh() 
 
    while solved == 0: 
        r = scr.getch() 
        subdials[p] = clear 
        currd = 'd'+str(p) 
 
        if r == ord('q') or r == ord('Q'): 
            break 
        elif r == curses.KEY_LEFT: 
            if p > 0 and p < 2: 
                p -= 1 
            else: pass 
        elif r == curses.KEY_RIGHT: 
            if p >= 0 and p < 1: 
                p += 1 
            else: pass 
        elif r == curses.KEY_UP: 
            if d[currd]['val'] >= 0 and d[currd]['val'] < 5: 
                d[currd]['val'] += 1 
                d[currd]['disp'] = dial[d[currd]['val']] 
            else: pass 
        elif r == curses.KEY_DOWN: 
            if d[currd]['val'] > 0 and d[currd]['val'] <= 5: 
                d[currd]['val'] -= 1 
                d[currd]['disp'] = dial[d[currd]['val']] 
            else: pass 
        else: pass 
 
        subdials[p] = pointer 
        dials = [d['d0']['disp'],d['d1']['disp']] 
 
        newscr.addstr(4,8,''.join(dials)) 
        newscr.addstr(6,8,''.join(subdials)) 
        newscr.refresh() 
 
        if d['d0']['val'] == 5 and d['d1']['val'] == 3: 
            solved = 1 
 
    if solved == 0: 
        scr.addstr(maxy-1,0,"You can't figure out the lock.") 
    else: 
        scr.addstr(maxy-1,0,"The lock is open!") 
    scr.getch() 
    scr.clear() 
    return solved 
 
def box(): 
    solved = curses.wrapper(spin) 
    return solved 

有两种方法可以退出“盒子”功能:按“q”退出,或者通过解谜。第一次退出 curses(无论哪种方式),没问题。但是,如果我再次调用“box”,问题很快就会出现。

首先,在 curses 窗口中,我的函数被指示传递的任何键输入都会回显到屏幕上。其次,更糟糕的是,当你第二次退出拼图时——无论是退出还是获胜——noecho 和 cbreak 都没有关闭,所以我的终端已经塞满了将被重置。

(注意:如果我继续调用“box”,则 curses 窗口本身不再回显按键输入,但我的终端不会恢复正常。)

我一辈子都弄不明白是什么导致了这种行为。帮助!

请您参考如下方法:

我将 Python 更新到 2.7.3,问题消失了。万岁!