6

I'm using Python curses and trying to initialize a new color using curses.init_color(). Even after initializing a new RGB value and assigning it to a pair, the changes won't take effect.

My terminal supports color change since curses.can_change_color() returns True. I've also checked the color index I changed using curses.color_content() - it returned the RGB values I specified in init_color(). I've also called curses.start_color() once at the beginning.

Am I missing something? What do I have to do to make the changes in init_color() take place? Code below:

    curses.start_color()
    curses.init_color(17, 200,200,200)

    curses.init_pair(1, curses.COLOR_MAGENTA, curses.COLOR_BLACK)    
    curses.init_pair(2, curses.COLOR_RED, curses.COLOR_BLACK)
    curses.init_pair(3, curses.COLOR_CYAN, curses.COLOR_BLACK)
    curses.init_pair(4, 17, curses.COLOR_BLACK)

    print curses.can_change_color() #returns True
    print curses.color_content(17) #(200,200,200), 
    stdscr.addstr("test",curses.color_pair(4)) #yet this text is blue

Am I missing something?

1 Answers1

2

Your color is just too dark. Try another, more bright color e.g. (800,800,0) to see yellow.

As the documentation states, each RGB component can vary between 0 and 1000, so if we map the (200, 200, 200) color to the standard 8-bit scheme, we get something like that http://colorpeek.com/#rgb(51,51,51).

You can run this demo and see that the init_color, init_pair and any other functions work as expected. Firstly it prints 8 colors while varying each component only between values 0 and 200. Then it prints more complete palette when components are varying in range (0, 200, 400, 600, 800, 1000)

# -*- coding: utf-8 -*-
import curses


def demo(screen):
    # save the colors and restore it later
    save_colors = [curses.color_content(i) for i in range(curses.COLORS)]
    curses.curs_set(0)
    curses.start_color()

    # use 250 to not interfere with tests later
    curses.init_color(250, 1000, 0, 0)
    curses.init_pair(250, 250, curses.COLOR_BLACK)
    curses.init_color(251, 0, 1000, 0)
    curses.init_pair(251, 251, curses.COLOR_BLACK)

    screen.addstr(0, 20, 'Test colors for r,g,b = {0, 200}\n',
                  curses.color_pair(250) | curses.A_BOLD | curses.A_UNDERLINE)
    i = 0
    for r in (0, 200):
        for g in (0, 200):
            for b in (0, 200):
                i += 1
                curses.init_color(i, r, g, b)
                curses.init_pair(i, i, curses.COLOR_BLACK)
                screen.addstr('{},{},{}  '.format(r, g, b), curses.color_pair(i))

    screen.addstr(3, 20, 'Test colors for r,g,b = {0..1000}\n',
                  curses.color_pair(251) | curses.A_BOLD | curses.A_UNDERLINE)
    for r in range(0, 1001, 200):
        for g in range(0, 1001, 200):
            for b in range(0, 1001, 200):
                i += 1
                curses.init_color(i, r, g, b)
                curses.init_pair(i, i, curses.COLOR_BLACK)
                # screen.addstr('{},{},{} '.format(r, g, b), curses.color_pair(i))
                screen.addstr('test ', curses.color_pair(i))

    screen.getch()
    # restore colors
    for i in range(curses.COLORS):
        curses.init_color(i, *save_colors[i])


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

Also, when you change colors with init_color, make sure that you restore them before exiting your program, as the terminal colors in the current session will not restore even when you exit your curses program (color not ended in curses).

enter image description here

tsionyx
  • 1,435
  • 1
  • 16
  • 28