34

我无法让终端调色板与诅咒一起使用。

import curses

def main(stdscr):
    curses.use_default_colors()
    for i in range(0,7):
        stdscr.addstr("Hello", curses.color_pair(i))
    stdscr.getch()

curses.wrapper(main)

此 python 脚本产生以下屏幕:

在此处输入图像描述

但是,我的 gnome-terminal 调色板中确实有更多颜色。我如何在 curses 中访问它们?

4

7 回答 7

60

以下是我在自己的电脑(Ubuntu 14.04,python 3)上通过实验得出的。

  • 有 256 种颜色(由前 8 位定义)。
  • 其他位用于附加属性,例如突出显示。
  • 将数字 -1 作为颜色传递回默认的背景和前景色。
  • 颜色对 0 (mod 256) 固定在 (-1, -1)。
  • 颜色 0 到 15 是终端调色板颜色。

考虑以下测试代码。将此添加到您的.bashrc

# Set proper $TERM if we are running gnome-terminal
if [ "$COLORTERM" == "gnome-terminal" ]
then
    TERM=xterm-256color
fi

把它放在一个python文件中并运行它。

import curses

def main(stdscr):
    curses.start_color()
    curses.use_default_colors()
    for i in range(0, curses.COLORS):
        curses.init_pair(i + 1, i, -1)
    try:
        for i in range(0, 255):
            stdscr.addstr(str(i), curses.color_pair(i))
    except curses.ERR:
        # End of screen reached
        pass
    stdscr.getch()

curses.wrapper(main)

运行它将产生以下输出。

截屏

如您所见,颜色对 1-16 是前景色的终端调色板。

于 2014-03-04T08:30:09.533 回答
16

终端“调色板”由终端应用程序本身设置,以将默认的诅咒颜色映射到特定于应用程序的“解释”。如果您使用红色,终端可以选择将其显示为酒红色或樱桃红,或者如果用户愿意,可以选择完全不同的颜色。

换句话说,只需使用诅咒颜色(结合或不结合明亮或闪烁修饰符),事情就应该正常工作。

我相信这个curses.use_default_colors()电话只是提供了透明度;use_default_colors()它是对ncurses API 函数的直接调用。ncurses 颜色是基于调色板的;curses.init_pair()您需要使用调用设置每个对号的颜色属性,然后从调色板中选择一个颜色对curses.color_pair()以显示具有该特定对的文本;addstr()或直接为给定的调用构建文本属性。

于 2013-09-08T13:27:58.977 回答
11

我目前将这些行放在我的脚本前面。

curses.use_default_colors()
for i in range(0, curses.COLORS):
    curses.init_pair(i, i, -1);

我不知道这是否是最好的解决方案,但至少它会产生一些与终端调色板一致的颜色对。

于 2013-09-08T12:08:44.887 回答
6

我没有代表点将此作为对 Chiel 10 Brinke 出色答案的评论提交,所以我将在这里提供他的颜色脚本的更有用的版本:

import curses
def main(stdscr):
    curses.start_color()
    curses.use_default_colors()
    for i in range(0, curses.COLORS):
        curses.init_pair(i + 1, i, -1)
    stdscr.addstr(0, 0, '{0} colors available'.format(curses.COLORS))
    maxy, maxx = stdscr.getmaxyx()
    maxx = maxx - maxx % 5
    x = 0
    y = 1
    try:
        for i in range(0, curses.COLORS):
            stdscr.addstr(y, x, '{0:5}'.format(i), curses.color_pair(i))
            x = (x + 5) % maxx
            if x == 0:
                y += 1
    except curses.ERR:
        pass
    stdscr.getch()
curses.wrapper(main)
于 2017-01-06T17:41:46.317 回答
3

您可以通过以下culour方式安装来使用该软件包:

pip install culour

然后你可以用它来打印颜色来诅咒:

culour.addstr(window, "colored string")
于 2017-07-27T13:14:30.407 回答
1

curses.use_default_colors()只需将默认 fg 或 bg 颜色设置为 -1,从手册页“init_pair(x,COLOR_RED,-1)将在默认背景init_pair(x,-1,COLOR_BLUE)上将 x 对初始化为红色,并将 x 在蓝色上初始化为默认前景。”

我一直认为 curses 只支持名为“curses.COLOR_...”的 8 个,通常这就足够了,但我想在我的应用程序中添加一些香料,所以很短的时间搜索就找到了我。大多数术语很可能支持 256 色,您可以使用上面的@Hristo Eftimov 的代码来打印所支持的内容。我决定制作一个备用颜色选择器,它将 x 颜色编号的示例显示为前景和背景。方向键左/右或键 a/d 更改要更改的属性,+/- 增加/减少颜色编号,q 或 esc 退出。


    #!/usr/bin/python
    
    from traceback import format_exc
    import sys, os, time, re, curses
    import locale
    locale.setlocale(locale.LC_ALL, '')
    os.environ.setdefault('ESCDELAY', '250')
    os.environ["NCURSES_NO_UTF8_ACS"] = "1"
    
    move_dirs = {curses.KEY_DOWN : (1, 0), curses.KEY_UP : (-1, 0), curses.KEY_RIGHT : (0, 1), curses.KEY_LEFT : (0, -1),
                 ord('s') : (1, 0), ord('w') : (-1, 0), ord('d') : (0, 1), ord('a') : (0, -1)}
    
    colors = {'white': curses.COLOR_WHITE, 'red': curses.COLOR_RED, 'green': curses.COLOR_GREEN,
              'yellow': curses.COLOR_YELLOW, 'blue': curses.COLOR_BLUE, 'magenta': curses.COLOR_MAGENTA,
              'cyan': curses.COLOR_CYAN, 'black': curses.COLOR_BLACK}
    
    class SuspendCurses():
        def __enter__(self):
            curses.endwin()
        def __exit__(self, exc_type, exc_val, tb):
            newscr = curses.initscr()
            newscr.refresh()
            curses.doupdate()
    
    def cp(i):
        return curses.color_pair(i)
    
    def set_pairs(fg, bg):
        curses.init_pair(1, fg, colors['black'])
        curses.init_pair(2, fg, colors['yellow'])
        curses.init_pair(3, fg, colors['white'])
        curses.init_pair(4, fg, colors['red'])
        curses.init_pair(5, colors['black'], bg)
        curses.init_pair(6, colors['yellow'], bg)
        curses.init_pair(7, colors['white'], bg)
        curses.init_pair(8, colors['red'], bg)
    
    def main_loop(stdscr):
        ret = 0
        EXIT = False
        try:
            curses.curs_set(1) #set curses options and variables
            curses.noecho()
            curses.cbreak()
            maxc = curses.COLORS
            maxy, maxx = stdscr.getmaxyx()
            if maxy < 10 or maxx < 65:
                with SuspendCurses():
                    print('Terminal window needs to be at least 10h by 65w')
                    print('Current h:{0}  and w:{1}'.format(maxy, maxx))
                ret = 1
                EXIT = True
            stdscr.refresh()
            h, w = 10, 65
            test_win = curses.newwin(h, w, 0, 0)
            stdscr.nodelay(1)
            test_win.leaveok(0)
            test_win.keypad(1)
            test_win.bkgd(' ', cp(0))
            test_win.box()
            cursor = [2, 0]
            test_win.move(2, 2+cursor[1]*20)
            fgcol, bgcol = 1, 1
            set_pairs(fgcol, bgcol)
            test_win.refresh()
            cursor_bounds = ((0,0),(0,1))
            teststr = '! @ # $ % ^ & *     _ + - = '
            k, newk = 1, 2
            while not EXIT:
                if k > -1:
                    test_win.clear()
                    if k in move_dirs.keys():  #move cursor left or right with wrapping
                        cursor[1] += move_dirs[k][1]
                        if cursor[1] > cursor_bounds[1][1]: cursor[1] = cursor_bounds[1][0]
                        if cursor[1] < cursor_bounds[1][0]: cursor[1] = cursor_bounds[1][1]
                    if k == 45:  #decr currently selected attr
                        if cursor[1] == 0:
                            fgcol -= 1
                            if fgcol < 0: fgcol = maxc-1
                        else:
                            bgcol -= 1
                            if bgcol < 0: bgcol = maxc-1
                        set_pairs(fgcol, bgcol)
                    if k == 43:  #incr currently selected attr
                        if cursor[1] == 0:
                            fgcol += 1
                            if fgcol > maxc-1: fgcol = 0
                        else:
                            bgcol += 1
                            if bgcol > maxc-1: bgcol = 0
                        set_pairs(fgcol, bgcol)
                    if k in (ord('q'), 27):
                        EXIT = True
                    test_win.addstr(1, 10, '{0} colors supported'.format(maxc), cp(0))
                    test_win.addstr(2, 2, 'FG: {0}  '.format(fgcol), cp(0))
                    test_win.addstr(2, 32, 'BG: {0}  '.format(bgcol), cp(0))
                    for i in range(1,5):
                        test_win.addstr(3+i, 2, teststr, cp(i))
                        test_win.addstr(3+i, 32,teststr, cp(i+4))
                    test_win.move(1, 2+cursor[1]*30)
                    test_win.box()
                    test_win.refresh()
                    curses.napms(10)
                newk = stdscr.getch()
                if newk != k:
                    k = newk
        except KeyboardInterrupt:
            pass
        except:
            ret = 1
            with SuspendCurses():
                print(format_exc())
        finally:
            return ret
    
    if __name__ == '__main__':
        try:
            _ret = curses.wrapper(main_loop)
        except Exception as e:
            print(e)
        finally:
            print('Exit status ' + str(_ret))
            sys.exit(_ret)

截屏:

截屏

于 2020-08-20T10:44:29.130 回答
0

迟到的答案,但可能会帮助其他诅咒新手。

curses.start_color(由 调用curses.wrapper)初始化 8 种基本颜色,因此可以假设您可以仅用于curses.color_pair(i)显示颜色。但是curses不仅有colors,也有color_pairs,而且只能用后者来显示颜色,但start_color只初始化colors,use_default_colors只初始化颜色号-1。

这意味着在此之后您没有设置任何颜色对,只有颜色。在绘制之前,您必须手动设置颜色对。如果您愿意,您也可以更改个别颜色的定义,但正如其他人所展示的那样,您通常已经设置了很多。

TL;博士:

如果您在调用wrapperorstart_color和之后无法显示颜色,您可能会错过这样一个事实,即您必须在绘制颜色之前use_default_colors设置颜色对。init_pair

于 2022-02-12T22:16:19.190 回答