为什么我的 Python 中的 Curses 边框消失了?

Why is my Curses border in Python disappearing?

我正在尝试使用 Python 进入 Curses,我对这两个主题都很陌生。我正在尝试制作一个可滚动的菜单对象,到目前为止它看起来还不错,但我遇到的问题是当滚动浏览一些测试数据时,window 边框消失了。我在代码中的几个点尝试了 window.clear() 和 window.refresh() 但我没有做任何事情使边界持久化。

#!/usr/bin/python

import curses
import curses.panel

class CursesMenu():

    pos = 0
    c = None
    menuItems = None
    selection = None
    dimensions = None
    MAX_DISPLAYED = 5
    displayList = list(range(MAX_DISPLAYED))
    subwin_key_up = None
    subwin_key_down = None

    def __init__(self, menuItems=None):
        self.menuItems = menuItems
        curses.wrapper(self.main_menu, menuItems)

    def scrollDisplayUp(self): #shift each element of displayList down one
        for i in range(len(self.displayList)):
            self.displayList[i] -= 1

    def scrollDisplayDown(self): #shift each element of displayList up one
        for i in range(len(self.displayList)):
            self.displayList[i] += 1

    def posUp(self, win): # Lower pos = higher placement
        if self.pos == 0: #loop back around
            self.pos = len(self.menuItems) - 1
            self.displayList = list(range(len(self.menuItems) - self.MAX_DISPLAYED, len(self.menuItems)))
            win.clear()
        else:
            self.pos -= 1

    def posDown(self, win): # Higher pos = lower placement
        if self.pos >= len(self.menuItems) - 1: #loop back around
            self.pos = 0
            self.displayList = list(range(self.MAX_DISPLAYED))
            win.clear()
        else:
            self.pos += 1

    def main_menu(self, win, menuItems=None):
        self.dimensions = win.getmaxyx()
        curses.curs_set(0) #invisible cursor
        curses.init_pair(1, curses.COLOR_BLACK, curses.COLOR_WHITE)
        highlighted = curses.color_pair(1)
        normal = curses.A_NORMAL

        sub = win.subwin(self.MAX_DISPLAYED + 2, 20, 1, 1)
        sub.immedok(True) #jet fuel can't melt steel beams
        sub.box()

        while self.c != ord('\n'): #run until 'enter' gets pressed
            sub.box()
            self.dimensions = win.getmaxyx()

            if self.c == curses.KEY_UP:
                self.posUp(sub)
                if self.pos <= self.displayList[0] - 1:
                    self.scrollDisplayUp()
                    sub.clear()
                    sub.refresh()
            if self.c == curses.KEY_DOWN:
                self.posDown(sub)
                if self.pos >= self.displayList[-1] + 1:
                    self.scrollDisplayDown()
                    sub.clear()
                    sub.refresh()

            for i, j in zip(self.displayList, range(self.MAX_DISPLAYED)):
                if i != self.pos:
                    sub.addstr(j+1, 1, menuItems[i], normal)
                else:
                    sub.addstr(j+1, 1, menuItems[i], highlighted)

            self.c = win.getch()
        self.selection = menuItems[self.pos]

这是我用来测试它的小脚本:

#!/usr/bin/python

import cursesmenu

menulist=['Alpha', 'Bravo', 'Charlie', 'Delta', 'Echo', 'Foxtrot', 'Golf', 'Hotel', \
'India', 'Juliett', 'Kilo', 'Lima', 'Mike', 'November', 'Oscar', 'Papa', 'Quebec', \
'Romeo', 'Sierra', 'Tango', 'Uniform', 'Victor', 'Whiskey', 'Xray', 'Yankee', 'Zulu']

m = cursesmenu.CursesMenu(menulist)
print m.selection
print m.dimensions

阅读脚本至少发现两个问题:

  • sub 是绘制框的位置,它是 win 的子项。您正在阅读 win,它执行 refresh(覆盖 sub)。请参阅 manual page
  • 有几个地方您可以清除 sub,这也会清除方框。

谢谢 Anand,它解决了消失的边框问题,但后来我发现陈旧的文字仍然存在。我通过在 sub.border(0) 和 sub.refresh() 之后放回 sub.clear() 来解决这个问题。