библиотеки цветных терминалов - PullRequest
2 голосов
/ 27 ноября 2011

Я пытаюсь реализовать цветовую циклизацию в моем тексте на Python ... Этот вопрос был отредактирован и повторно передан как еще один вопрос из-за значительного изменения контекста.см. здесь вместо.

этот вопрос был больше о том, какую библиотеку мне следует использовать - termcolor , colorama , curses и цветной рецепт ANSI ,

код до сих пор:

#!/usr/bin/env python

'''
        "arg" is a string or None
        if "arg" is None : the terminal is reset to his default values.
        if "arg" is a string it must contain "sep" separated values.
        if args are found in globals "attrs" or "colors", or start with "@" \
    they are interpreted as ANSI commands else they are output as text.
        @* commands:

            @x;y : go to xy
            @    : go to 1;1
            @@   : clear screen and go to 1;1
        @[colour] : set foreground colour
        ^[colour] : set background colour

        examples:
    echo('@red')                  : set red as the foreground color
    echo('@red ^blue')             : red on blue
    echo('@red @blink')            : blinking red
    echo()                       : restore terminal default values
    echo('@reverse')              : swap default colors
    echo('^cyan @blue reverse')    : blue on cyan <=> echo('blue cyan)
    echo('@red @reverse')          : a way to set up the background only
    echo('@red @reverse @blink')    : you can specify any combinaison of \
            attributes in any order with or without colors
    echo('@blink Python')         : output a blinking 'Python'
    echo('@@ hello')             : clear the screen and print 'hello' at 1;1

colours:
{'blue': 4, 'grey': 0, 'yellow': 3, 'green': 2, 'cyan': 6, 'magenta': 5, 'white': 7, 'red': 1}

    '''

'''
    Set ANSI Terminal Color and Attributes.
'''
from sys import stdout
import random
import sys
import time

esc = '%s['%chr(27)
reset = '%s0m'%esc
format = '1;%dm'
fgoffset, bgoffset = 30, 40
for k, v in dict(
    attrs = 'none bold faint italic underline blink fast reverse concealed',
    colours = 'grey red green yellow blue magenta cyan white'
).items(): globals()[k]=dict((s,i) for i,s in enumerate(v.split()))

def echo(arg=None, sep=' ', end='\n', rndcase=True, txtspeed=0.03):

    cmd, txt = [reset], []
    if arg:
        # split the line up into 'sep' seperated values - arglist
            arglist=arg.split(sep)

        # cycle through arglist - word seperated list 
            for word in arglist:

                if word.startswith('@'):
            ### First check for a colour command next if deals with position ###
                # go through each fg and bg colour  
                tmpword = word[1:]
                    if tmpword in colours:
                        cmd.append(format % (colours[tmpword]+fgoffset))
                    c=format % attrs[tmpword] if tmpword in attrs else None
                    if c and c not in cmd:
                                cmd.append(c)
                    stdout.write(esc.join(cmd))
                    continue
                # positioning (starts with @)
                word=word[1:]
                if word=='@':
                    cmd.append('2J')
                    cmd.append('H')
                    stdout.write(esc.join(cmd))
                    continue
                else:
                    cmd.append('%sH'%word)
                    stdout.write(esc.join(cmd))
                    continue

                if word.startswith('^'):
            ### First check for a colour command next if deals with position ###
                # go through each fg and bg colour  
                tmpword = word[1:]
                    if tmpword in colours:
                        cmd.append(format % (colours[tmpword]+bgoffset))
                    c=format % attrs[tmpword] if tmpword in attrs else None
                    if c and c not in cmd:
                                cmd.append(c)
                    stdout.write(esc.join(cmd))
                    continue                    
            else:
                for x in word:  
                    if rndcase:
                        # thankyou mark!
                        if random.randint(0,1):
                                x = x.upper()
                        else:
                            x = x.lower()
                    stdout.write(x)
                    stdout.flush()
                    time.sleep(txtspeed)
                stdout.write(' ')
                time.sleep(txtspeed)
    if txt and end: txt[-1]+=end
    stdout.write(esc.join(cmd)+sep.join(txt))

if __name__ == '__main__':

    echo('@@') # clear screen
    #echo('@reverse') # attrs are ahem not working
    print 'default colors at 1;1 on a cleared screen'
    echo('@red hello this is red')
    echo('@blue this is blue @red i can ^blue change @yellow blah @cyan the colours in ^default the text string')
    print
    echo()
    echo('default')
    echo('@cyan ^blue cyan blue')
#   echo('@cyan ^blue @reverse cyan blue reverse')
#   echo('@blue ^cyan blue cyan')
    #echo('@red @reverse red reverse')
#    echo('yellow red yellow on red 1')
#    echo('yellow,red,yellow on red 2', sep=',')
#    print 'yellow on red 3'

#        for bg in colours:
#                echo(bg.title().center(8), sep='.', end='')
#                for fg in colours:
#                        att=[fg, bg]
#                        if fg==bg: att.append('blink')
#                        att.append(fg.center(8))
#                        echo(','.join(att), sep=',', end='')

    #for att in attrs:
    #   echo('%s,%s' % (att, att.title().center(10)), sep=',', end='')
    #   print

    from time import sleep, strftime, gmtime
    colist='@grey @blue @cyan @white @cyan @blue'.split()
    while True:
        try:
            for c in colist:
                sleep(.1)
                echo('%s @28;33 hit ctrl-c to quit' % c,txtspeed=0)
            #echo('@yellow @6;66 %s' % strftime('%H:%M:%S', gmtime()))
        except KeyboardInterrupt:
            break
        except:
            raise
    echo('@10;1')
    print

Ответы [ 2 ]

1 голос
/ 28 ноября 2011

Вот несколько методов, которые можно попробовать:

  1. Этот блок кода создает списки фактических escape-строк.Он использует список понимания , чтобы перебрать список имен цветов и найти escape-коды в вашем colour словаре..split() - это просто ленивый способ создания списка строк без ввода большого количества последовательностей кавычка-кавычка.

    color_cycle = [
        [colour[name] for name in 'bldylw bldred bldgrn bldblu txtwht'.split()],
        [colour[name] for name in 'txtblu txtcyn'.split()]
    ]
    
  2. Позже ваша функция может использовать эти списки с помощьюсоздание итератора .Этот конкретный итератор использует стандартную библиотечную функцию itertools.cycle , которая повторяет последовательность бесконечно.Здесь я предполагаю, что вы хотите написать каждый символ строки разным цветом.

    import itertools
    
    # Create an iterator for the selected color sequence.
    if colourc:
        icolor = itertools.cycle(color_cycle[colourc - 1])
    
    for a in stringy:
        # Write out the escape code for next color
        if colourc:
            color = next(icolor)
            sys.stdout.write(color)
    
  3. Вот еще один способ выбора случайного регистра.В Python ноль считается ложным:

        if rndcase:
            if random.randint(0,1):
                a = a.upper()
            else:
                a = a.lower()
    
0 голосов
/ 27 ноября 2011

Здесь есть пара проблем.Прежде всего, почему вы используете 0 и 1 вместо True и False в переменной colourc? намного легче сказать, что происходит, если вы используете правильные логические значения.

В первом блоке if, если colourc не равен 0, вы записываете всю строку в стандартный вывод.Я удивлен, что на самом деле это не печатается с цветами, как это происходит, когда я запускаю код.

Когда речь идет о печати по одному символу за раз, именно здесь ваш код сталкивается с проблемами.Экранирующие последовательности ANSI не являются отдельными символами и не могут рассматриваться как таковые.Во-первых, ваш случайный код падежа может заглушить любые ANSI-последовательности, в которые он попадает, путем случайного верхнего или нижнего регистра символов m или K. в последовательности.

Когда я запускаю ваш код, но с rndcase=FalseДаже один символ во временном коде работает нормально.

Вам следует заново продумать, как установить цвета на входе, чтобы, когда новый цвет вступил в силу, вы могли напечатать всю последовательность ANSI.с последующим следующим символом в выводе.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...