在 class python 和 kivy 中打印彩色字符串

Printing colored string in class python and kivy

代码没有 CLASS

import sys
from termcolor import colored
string="admin"
lista=["W","W","W","W","G"]
string1=""
for i in range(5):
    if lista[i]=="W":
        string1+=colored(string[i],'red')
    elif lista[i]=="G":
        string1+=colored(string[i],'green')
    else:
        string1+=colored(string[i],'blue')
print(string1)

使用这段代码,我可以根据相应索引中的列表变量打印出特定颜色的字母。然而:

.py文件

import kivy
kivy.require('1.11.1')
from kivy.app import App
from kivy.config import Config
from kivy.core.window import Window
from kivy.uix.widget import Widget
from kivy.lang import Builder
from kivy.uix.relativelayout import RelativeLayout
from kivy.uix.gridlayout import GridLayout
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.uix.textinput import TextInput
from kivy.uix.label import Label
from kivy.app import App
from random import choice
from termcolor import colored

Builder.load_file('GuessWord.kv')


class GuessWord(Widget):
    words=["words","crown","ideal"]
    word=choice(words)
    attempts=0
    listofguesses=[]
    accuratecolor=[]
    
    def ClearLetters(self):
        t1=self.ids['t1']
        t2=self.ids['t2']
        t3=self.ids['t3']
        t4=self.ids['t4']
        t5=self.ids['t5']
        listofletters=[t1,t2,t3,t4,t5]
        for i in range(5):
            listofletters[i].background_color=(1,1,1,1)
            listofletters[i].text=""
        
    def StartGame(self):
        self.attempts=0        
        self.word=choice(self.words)
        l1=self.ids['OUTPUT']
        l1.text=""
        listofletters=[]
        for i in range(5):
            name="t"+str(i)
            letter=self.ids[name]
            listofletters.append(name)
              
        for i in range(5):
            listofletters[i].background_color=(1,1,1,1)
            listofletters[i].text=""
        self.listofguesses=[]
        l2=self.ids['ATTEMPTS']
        l2.text=""
    
    def ShowPreviousWord(self):
        t1=self.ids['t1']
        t2=self.ids['t2']
        t3=self.ids['t3']
        t4=self.ids['t4']
        t5=self.ids['t5']
        listofletters=[t1,t2,t3,t4,t5]
        string=""
        for i in listofletters:
            string+=i.text
        coloredstring=""
        print(string)
        print(self.accuratecolor)
        
        for i in range(len(string)):
            if self.accuratecolor[i]=="W":
                coloredstring+=colored(string[i],'white')
            elif self.accuratecolor[i]=="Y":
                coloredstring+=colored(string[i],'yellow')
            elif self.accuratecolor[i]=="G":
                coloredstring+=colored(string[i],'green')            
        print(coloredstring)
        self.listofguesses.append(coloredstring)
        attempts=""
        for i in range(len(self.listofguesses)):
            attempts+=f'Attempt {i+1}: {self.listofguesses[i]}\n'           
        l1=self.ids['ATTEMPTS']
        l1.text=attempts
        
        
        
            
        
        
    def Check(self):
        self.attempts+=1
        t1=self.ids['t1']
        t2=self.ids['t2']
        t3=self.ids['t3']
        t4=self.ids['t4']
        t5=self.ids['t5']
        listofletters=[t1,t2,t3,t4,t5]
        outputstring=""
        accurateletters=0
        accuratecolor=[]
        for i in range(5):
            listofletters[i].background_color=(1,1,1,1)
        for i in range(len(listofletters)):
            if listofletters[i].text.lower()=="":
                outputstring+=f'You have not filled {i+1} letter\n'
                accuratecolor.append("W")
            elif listofletters[i].text.lower() in self.word:
                if listofletters[i].text.lower() == self.word[i]:
                    accuratecolor.append("G")
                    listofletters[i].background_color=(0, 255/256, 0, 1)
                    accurateletters+=1
                    outputstring+=f'{listofletters[i].text.upper()} - letter in accurate spot\n'
                else:
                    accuratecolor.append("Y")
                    listofletters[i].background_color=(228/256, 245/256, 39/256, 1)
                    outputstring+=f'{listofletters[i].text.upper()} - letter is in word, but not in this spot\n'
            else:
                accuratecolor.append("W")
                outputstring+=f'{listofletters[i].text.upper()} - no letter in the word\n'
                listofletters[i].bacground_color=(1,1,1,1)
        l1=self.ids['OUTPUT']
        l2=self.ids['ATTEMPTS']
        self.accuratecolor=accuratecolor
        if accurateletters==5:
            l1.text=f'You have won! You guessed the word after {self.attempts} attempts'
            l2.text=""
        else:
            l1.text=outputstring
        
        
        


class GuessWordApp(App):
    def build(self):
        return GuessWord()

if __name__ == '__main__':
    GuessWordApp().run()

.KV文件

<GuessWord>   
    RelativeLayout:
        size: root.width, root.height
        Label:
            pos_hint: {'center_x':0.5,'y':0.7}
            size_hint: 0.2,0.2
            text: "Guess the word!"
        Button:
            pos_hint: {'center_x':0.5,'y':0.67}
            size_hint: 0.5,0.1
            text: "Click here to start!"
            on_press: root.StartGame()
        GridLayout:
            id: word
            cols:5
            pos_hint:{'center_x':0.5,'y':0.5}
            size_hint:(1,0.15)                    
            TextInput:
                halign: "center"
                font_size: 70
                id: t1
                multiline: False
                focus: True
                on_text: t2.focus = True                    
            TextInput:
                halign: "center"
                font_size: 70
                id: t2 
                multiline: False
                on_text: t3.focus = True               
            TextInput:
                halign: "center"
                font_size: 70
                id: t3
                multiline: False
                on_text: t4.focus = True 
            TextInput:
                halign: "center"
                font_size: 70
                id: t4
                multiline: False
                on_text: t5.focus = True 
            TextInput:
                halign: "center"
                font_size: 70
                id: t5
                multiline: False
                on_text:
                    root.Check()
                    root.ShowPreviousWord()
                    t1.focus = True 
        GridLayout:
            cols:1
            pos_hint:{'center_x':0.5,'y':0.3}
            size_hint:(1,0.2)
            Button: 
                pos_hint:{'center_x':0.5,'y':0.4}
                text: "Check if it's your word!"
                on_press: 
                    root.Check()
                    root.ShowPreviousWord()
                    
                    
        Label:
            pos_hint:{'center_x':0.5,'y':-0.35}
            id: OUTPUT
        Label:
            pos_hint:{'center_x':0.2,'y':-0.35}
            id:ATTEMPTS

主要关注 .py 文件中的 ShowPreviousWord 函数,在该函数的开头(开始时,同时放置 5 个字母中的最后一个字母)它被赋予一个要打印的字符串并传递 listofcolors来自不同的功能。该代码与没有 class 的情况完全相同,但是打印结果不同。

例如,对于单词“admin”和 list=["W","W","W","W","G"] 它会打印出: ←[37ma←[0m←[37md←[0m←[37mm←[0m←[37mi←[0m←[32mn←[0m

同时,第一个代码按我希望的方式工作。为了增加问题,我想将彩色字符串传递给 kivy 标签并将其显示在屏幕上。为什么它不起作用?

此处着色是使用 Labelmarkup 属性完成的。并使用新函数设置颜色(十六进制)。

首先定义一个设置颜色(color)的函数为,

def set_color(letter, color):
    COLORS_DICT  = {"W" : "ffffff", "Y" : "ffff00", "G" : "00ff00"}
    c = COLORS_DICT.get(color, "W")
    return f"[color={c}]{letter}[/color]"

现在在方法 ShowPreviousWord 中使用它,

    def ShowPreviousWord(self):
        ...
        print(string)
        print(self.accuratecolor)

        coloredstring = "".join((set_color(l, c) for l, c in zip(string, self.accuratecolor)))

        print(coloredstring)
        ...

最后,在Label中激活markup进行渲染,

        Label:
            pos_hint:{'center_x':0.2,'y':-0.35}
            id:ATTEMPTS
            markup: True