Как установить цвет текста для градиентной текстуры в киве? - PullRequest
0 голосов
/ 18 марта 2020

Я использовал для создания Texture с градиентным цветом и установил фон Label, Button и др. c. Но мне интересно, как установить это color из Label?

Ответы [ 2 ]

0 голосов
/ 19 марта 2020

Звучит как забавная головоломка. Итак, вот что я придумал:

from kivy.lang import Builder
from kivy.graphics.texture import Texture
from kivy.properties import ObjectProperty, ListProperty
from kivy.uix.label import Label


class LabelGradient(Label):
    gradient = ObjectProperty(None)
    bg_color = ListProperty([0, 0, 0, 255])

    def __init__(self, **kwargs):
        super(LabelGradient, self).__init__(**kwargs)

        # bind to texture to trigger use of gradient
        self.bind(texture=self.fix_texture)

    def fix_texture(self, instance, texture):
        if self.gradient is None:
            return

        # unbind, so we don't loop
        self.unbind(texture=self.fix_texture)

        # The normal Label texture is transparent except for the text itself
        # This code changes the texture to make the text transparent, and everything else
        # gets set to self.bg_color (a property of LabelGradient)
        pixels = list(self.texture.pixels)
        for index in range(3, len(pixels)-4, 4):
            if pixels[index] == 0:
                # change transparent pixels to the bg_color
                pixels[index-3:index+1] = self.bg_color
            else:
                # make the text itself transparent
                pixels[index] = 0

        # create a new texture, blit the new pixels, and apply the new texture
        new_texture = Texture.create(size=self.texture.size, colorfmt='rgba')
        new_texture.blit_buffer(bytes(pixels), colorfmt='rgba', bufferfmt='ubyte')
        new_texture.flip_vertical()
        self.texture = new_texture

Builder.load_string('''
<LabelGradient>:
    canvas.before:
        # draw the gradient below the normal Label Texture
        Color:
            rgba: 1,1,1,1
        Rectangle:
            texture: self.gradient
            size: self.texture_size
            pos: int(self.center_x - self.texture_size[0] / 2.), int(self.center_y - self.texture_size[1] / 2.)
''')


if __name__ == '__main__':
    from kivy.app import App
    from kivy.lang import Builder

    class LabelGradientApp(App):
        grad = ObjectProperty(None)

        def build(self):
            # create a 64x64 texture, defaults to rgba / ubyte
            self.grad = Texture.create(size=(64, 64))

            # create 64x64 rgb tab, and fill with values from 0 to 255
            # we'll have a gradient from black to white
            size = 64 * 64 * 3
            buf = bytes([int(x * 255 / size) for x in range(size)])

            # then blit the buffer
            self.grad.blit_buffer(buf, colorfmt='rgb', bufferfmt='ubyte')
            return theRoot

    app = LabelGradientApp()

    theRoot = Builder.load_string('''
FloatLayout:
    LabelGradient:
        text: 'Abba Dabba Doo'
        font_size: 30
        gradient: app.grad
''')

    app.run()

Мой подход - сделать текст прозрачным и нарисовать градиент позади текста. Нормальный Texture, созданный Label, прозрачен, за исключением фактического текста.

Приведенный выше LabelGradient расширяет Label и dr aws градиент с использованием правила <LabelGradient> в kv. Метод fix_texture() связан со свойством texture Label, поэтому он вызывается, как только создается Texture. Метод fix_texture() делает фактический текст прозрачным и устанавливает для остальной части Texture значение bg_color.

0 голосов
/ 18 марта 2020

Вы не можете установить свойство color для градиента, это не то, что оно делает. Градиенты должны быть получены с использованием изображений или текстур, непосредственно применяемых к инструкциям вершин холста.

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