How to access some widget attribute from another widget in Kivy?
<p>Ok let's say I want that label in some widget to use text from label inside another widget:</p>

<pre><code>&lt;SubWidget@RelativeLayout&gt;:
    Label:
        text: str(root.parent.ids.first.text)

&lt;RootWidget&gt;:
    Label:
        id: first
        center_x: 100
        text: "text"

    SubWidget:
        id: second
        center_x: 200
</code></pre>

<p>This works but doesn't seem to be nice solution. If I'll place <code>first</code> inside another widget I'll need to change reference to that it everywhere in the code (that can lead to errors).</p>

<p>My first idea was at least to store reference to <code>first</code> at root level and reference to it:</p>

<pre><code>&lt;SubWidget@RelativeLayout&gt;:
    Label:
        text: str(root.parent.l.text)


&lt;RootWidget&gt;:
    l: first

    Label:
        id: first
        center_x: 100
        text: "text"

    SubWidget:
        id: second
        center_x: 200
</code></pre>

<p>But this leads to exception:</p>

<pre><code>AttributeError: 'NoneType' object has no attribute 'text'
</code></pre>

<p>This is confusing since if I'll write something like <code>text: str(root.parent.l)</code> I'll see <code>Label object</code> rather than <code>NoneType</code>.</p>

<p>So I have two questions:</p>

<ol>
<li>Why doesn't second solution works? How it can be fixed?</li>
<li>In general, what's the best way to access some widget attribute from another widget? Can I make it independent of widgets hierarchy?</li>
</ol>

<ol>
<li><p>The object property <code>l</code> probably gets populated <strong>after</strong> the first event loop iteration, while you are trying to access it within the first. You could delay it till the second iteration to make it work.</p></li>
<li><p>The most powerful approach is to bind those properties from inside python code, but there are some kv lang tricks to make it simpler. This is my favorite method:</p></li>
</ol>

<pre>BoxLayout

    Label
        id: label
        text: 'hello world'

    SubWidget
        label_text: label.text

&lt;SubWidget@BoxLayout>
    label_text: 'none'

    Label
        text: root.label_text
</pre>

python kivy kivy-language