CharlieB
CharlieB

Reputation: 744

Using nested Kivy parameters within a Widget's canvas

I'm making a Kivy layout using Kivy Language, and I've noticed that I can't seem to use nested parameters when defining the canvas of a Widget. This is what I mean:

Example 1 - this runs fine

<MainWidget>:

    Label:

        text: "Here is a button"
        var1: 1,0,0,1

        canvas.before:
            Color: 
                rgba: self.var1
            Rectangle:
                pos: self.pos
                size: self.size                   

Example 2 - this failes with TypeError: 'NoneType' object is not iterable

<MainWidget>:

    Label:

        text: "Here is a button"
        var1: 1,0,0,1
        var2: self.var1

        canvas.before:
            Color: 
                rgba: self.var2
            Rectangle:
                pos: self.pos
                size: self.size

Python code for both

from kivy.app import App
from kivy.uix.widget import Widget


class MainApp(App):

    def build(self):
        return MainWidget()


class MainWidget(Widget):
    pass


MainApp().run()

I think the problem here is that var2 is None until var1 is assigned, but this doesn't happen until after the object is initiated. Is there a way to do what I'm trying to do here?

N.B. This seems to only be a problem with the Widget's canvas. I can do e.g. this with no problems:

:

Label:

    text: "Here is a button"
    var1: 1,0,0,1
    var2: self.var1

    color: self.var2

Upvotes: 0

Views: 334

Answers (2)

el3ien
el3ien

Reputation: 5405

This happens for two reasons.
The self you are referring to, is referring to Color
If you give your label an id, then you can refer to its properties.
But in your case this would still not work, because the var2 will only be set to var1 after initiation of the object, so it is still ObjectProperty(None). And it will be None untill the next frame.

You can make it work, if you define var1 as a ListProperty in your class.

In py.

class MyLabel(Label):
    var2 = ListProperty([0,0,0,0])

Then in kv.

MyLabel:
    id: label
    text: "Here is a button"
    var1: 1,0,0,1
    var2: self.var1

    canvas.before:
        Color: 
            rgba: label.var2
        Rectangle:
            pos: label.pos
            size: label.size

Upvotes: 1

CharlieB
CharlieB

Reputation: 744

Thanks for @EL3PHANTEN for the tip: the following solution expands on his approach but doesn't require any modification to the Python or the creation of a custom class:

Python code: same as in the question

** Kivy Language**

<MainWidget>:

    Label:

        text: "Here is a button"
        var1: 1,1,0,1
        var2: self.var1

        canvas.before:
            Color:
                rgba: self.var2 if self.var2 is not None else [0,0,0,0]
            Rectangle: 
                pos: self.pos
                size: self.size

This works because all parameters defined by Kivy language seem to be set to None until they get a value.

Upvotes: 1

Related Questions