Python - Curses - Addstr -multicolored string/understanding functions

478 views Asked by At

I don't know what the right words are to ask my question, so please excuse the extra detail below. I am as much asking for the right words/concepts as for an answer to the specific question.

I'm trying to put a simple console in front of a script of mine using curses in Python. I want the console to look relatively familiar and have key shortcuts for 3 commands (Load, Exit, Continue). To highlight which key is the hotkey for an action, I wanted that letter to be in a different colour. (e.g. Exit with hotkey being the x). I figure this must be made up of 3 "addstr" commands- write the first letter in normal ("E"), then the x with a colour attribute, then "it" in normal colour again.

I thought that because I do this 3 times, and maybe more in future screens, I should make a function to do it for me to see if that works. What I can't figure out though, is how to edit the screen without hardcoding the function to the variable name. I want to be able to call the function in a number of different windows. I thought at first I could just pass the screen's variable into my function but that doesn't seem right.

Here is my pseudo code I started working on:

def keyString(menuString,fastChar,highlight,startX,startY,cScreen):
    #menuString is the word that has a letter to bring to attention
    #fastChar is the character that will be in a different colour
    #highlight is binary value to determine which colour pair to use
    #definition expects 'h' and 'n' to be colour pairs
    #startX and startY are the beginning cursor positions
    #cScreen would be global screen variable

    fCidx = menuString.find(fastChar) #index of the character to highlight
    fXadj = startX + fCidx #set the x position for character to highlight
    sHx = fXadj + 1 #set the x position for the remainder of the string
    fH = menuString[0:fCidx] #Slice the first half of the string
    sH = menuString[(fCidx+1):] #slice the remainder of the string

    if highlight:
            txtColor = h
    else:
            txtColor = n

    cScreen.addstr(startY,startX,fH,txtColor)
    cScreen.addstr(startY,fXadj,fastChar)
    cScreen.addstr(startY,sHx,sH,txtColor)

    return cScreen

Please ignore the awful variable names..I was getting tired of typing and started shorthanding. I realise that I didn't need to worry about explicitly stating x,y coords because the cursor position is remembered. So a lot of that can be cut out. I'm not asking for someone to fix my function. I just don't have a concept of how to have a function that will write out a word using different colours for different characters. I could probably stick a "global screen" in the function and only use it for editing "screen", but then (for example) I wouldn't be able to use the function for "screen2".

1

There are 1 answers

1
BSAFH On

If it helps anyone searching in the future, I found that I can use Windows (curses.newwin) and those can be fed into, and returned from functions.

So for example, if the above code was in a file called "curse_tools.py":

import curses
import curse_tools
def Main(screen):
    curses.init_pair(1,curses.COLOR_GREEN, curses.COLOR_BLACK)
    curses.init_pair(2,curses.COLOR_BLACK, curses.COLOR_GREEN)
    n = curses.color_pair(1)
    h = curses.color_pair(2)
    curse_tools.n = n
    curse_tools.h = h

    try:
            screen.border(0)
            box1 = curses.newwin(20, 20, 5, 5)
            box1.box()
            box1=curse_tools.keyString("Exit","x",False,1,1,box1)
            screen.refresh()
            box1.refresh()
            screen.getch()

    finally:
            curses.endwin()

curses.wrapper(Main)

This code would work. I'm going to re-write my original code because I learned a lot along the way but maybe a future beginner will somehow come across this question so I thought I'd post the 'solution'. Although I still don't know the right words.

Most of the code in this post came from Why won't my curses box draw? (in case it looks familiar)