kivy Line with gradient color

53 views
Skip to first unread message

Degenerate Tech

unread,
May 12, 2024, 5:19:11 AMMay 12
to Kivy users support
i have Line i want ro fill its texture with gradient color . how to do ?

elli...@cox.net

unread,
May 12, 2024, 12:09:06 PMMay 12
to kivy-...@googlegroups.com
If you are creating a simple horizontal or vertical line, you could create a narrow rectangle and set the texture to be a gradient.
Contribute to kengoon/KivyGradient development by creating an account on GitHub.




From: kivy-...@googlegroups.com <kivy-...@googlegroups.com> on behalf of Degenerate Tech <sksah...@gmail.com>
Sent: Sunday, May 12, 2024 2:19 AM
To: Kivy users support <kivy-...@googlegroups.com>
Subject: [kivy-users] kivy Line with gradient color
 
i have Line i want ro fill its texture with gradient color . how to do ?

--
You received this message because you are subscribed to the Google Groups "Kivy users support" group.
To unsubscribe from this group and stop receiving emails from it, send an email to kivy-users+...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/kivy-users/4a584031-c23c-48c9-87a7-60e0e6ceda8dn%40googlegroups.com.

Degenerate Tech

unread,
May 13, 2024, 3:56:18 AMMay 13
to Kivy users support
How to curve it. I want lines so I can it circle or other lines types

elli...@cox.net

unread,
May 13, 2024, 8:45:06 PMMay 13
to Kivy users support
Looking at the docs it appears that all of the drawing instructions can take a texture, so I created a small experiment.
I copied the core of the KivyGradient code ( it is just 2 methods) and drew a random line with a texture.  One strange effect, the texture needed to be updated or the line turns white.  I bound to the Window draw... This feels hacky.  It might be worth copying the gradient to a file,  and trying the source attribute.

Anyway - here is the code.

from kivy.app import App
from kivy.lang import Builder
from kivy.uix.widget import Widget
from kivy.graphics.texture import Texture
from kivy.properties import ObjectProperty
from kivy.utils import colormap, get_random_color
from kivy.clock import Clock
from kivy.core.window import Window
from itertools import chain


kv = """
<GradientWidget>:
    canvas:
        Line:
            width: 2
            points: [100, 100, 600, 100, 100, 200, 300, 500]  # just some random points
            texture: self.gradient

BoxLayout:
    GradientWidget:
        id: gw
"""


class Gradient:
    """
    """

    @staticmethod
    def horizontal(*args):
        """
        Create a horizontal gradient
        :param args: colors that will make up the gradient in order
        :return: A Texture of the desired gradient
        """
        texture = Texture.create(size=(len(args), 1), colorfmt='rgba')
        buf = bytes([int(v * 255) for v in chain(*args)])  # flattens
        texture.blit_buffer(buf, colorfmt='rgba', bufferfmt='ubyte')
        return texture

    @staticmethod
    def vertical(*args):
        """
        Create a Vertical gradient
        :param args: colors that will make up the gradient in order
        :return: A Texture of the desired gradient
        """
        texture = Texture.create(size=(1, len(args)), colorfmt='rgba')
        buf = bytes([int(v * 255) for v in chain(*args)])  # flattens
        texture.blit_buffer(buf, colorfmt='rgba', bufferfmt='ubyte')
        return texture


class GradientWidget(Widget):
    gradient = ObjectProperty()

    def set_gradient(self, *args):
        try:
            colors = [colormap[arg] for arg in args]
            self.gradient = Gradient.horizontal(*colors)
        except KeyError:
            print('KeyError: invalid color used')


class GradientExperiment(App):
    def build(self):
        Window.bind(on_draw=self.win_update)  # need to update texture on redraw?
        return Builder.load_string(kv)

    def set_colors(self):
        self.root.ids.gw.set_gradient('red', 'yellow', 'green', 'lightgreen', 'lightblue',
                                      'darkblue', 'violet')

    def set_random_colors(self, dt):
        self.root.ids.gw.gradient = Gradient.horizontal(*[get_random_color() for _ in range(5)])

    def win_update(self, *args):
        self.set_colors()


GradientExperiment().run()




Sent: Monday, May 13, 2024 12:56 AM

To: Kivy users support <kivy-...@googlegroups.com>
Subject: Re: [kivy-users] kivy Line with gradient color
 

Degenerate Tech

unread,
May 14, 2024, 9:16:12 AMMay 14
to Kivy users support
Yeah . Great . Same thing I was thinking. Line also take texture 👍👍👍👍👍

Degenerate Tech

unread,
May 26, 2024, 9:37:34 AMMay 26
to Kivy users support
see in this code gradient textture is not loading . please see or where i am wrong ?
meter.kv
meter.py

ELLIOT GARBUS

unread,
May 26, 2024, 12:02:43 PMMay 26
to Kivy users support
I suspect you are seeing the same issue I saw, note in my code that I am updating the texture on each redraw by binding to the Window on_draw event. 


Sent: Sunday, May 26, 2024 6:37 AM

ELLIOT GARBUS

unread,
May 26, 2024, 12:09:53 PMMay 26
to Kivy users support


From: ELLIOT GARBUS <elli...@cox.net>
Sent: Sunday, May 26, 2024 9:02 AM

ElliotG

unread,
May 26, 2024, 4:13:38 PMMay 26
to Kivy users support
I updated my earlier experiment... I was not able to get the reload_observer to operate ( This was a surprise).  I just do not understand OGL well enough I suppose.  
This still feels like a hack - but it is better.

from kivy.app import App
from kivy.lang import Builder
from kivy.uix.widget import Widget
from kivy.graphics.texture import Texture
from kivy.utils import colormap
from kivy.graphics import Line
from kivy.clock import Clock

from itertools import chain


kv = """
BoxLayout:
    GradientWidget:
        id: gw
"""


class GradientWidget(Widget):

    def __init__(self, **kwargs):
        super().__init__(**kwargs)
        self.texture = None
        self.buf = None

    def horizontal(self, *args):

        """
        Create a horizontal gradient
        :param args: colors that will make up the gradient in order
        :return: None
        From: https://github.com/kengoon/KivyGradient
        """
        self.texture = Texture.create(size=(len(args), 1), colorfmt='rgba')
        # self.texture.add_reload_observer(self.rlo)  # not tiggered?
        self.buf = bytes([int(v * 255) for v in chain(*args)])  # flattens
        Clock.schedule_interval(self.update, 0)

    def rlo(self):
        print('rlo')  # Never called... ???

    def update(self, *args):
        print('update')
        self.texture.blit_buffer(self.buf, colorfmt='rgba', bufferfmt='ubyte')
        with self.canvas:
            Line(width=2, points=[100, 100, 600, 100, 100, 200, 300, 500], texture=self.texture)

    def set_gradient(self, *args):
        print('set gradient')

        try:
            colors = [colormap[arg] for arg in args]
            self.horizontal(*colors)

        except KeyError:
            print('KeyError: invalid color used')


class GradientExperiment(App):
    def build(self):
        return Builder.load_string(kv)

    def set_colors(self):
        self.root.ids.gw.set_gradient('red', 'yellow', 'green', 'lightgreen', 'lightblue',
                                      'darkblue', 'violet')

    def on_start(self):
        self.set_colors()


GradientExperiment().run()


Reply all
Reply to author
Forward
0 new messages