How to access some widget attribute from another w

2019-03-05 12:38发布

问题:

Ok let's say I want that label in some widget to use text from label inside another widget:

<SubWidget@RelativeLayout>:
    Label:
        text: str(root.parent.ids.first.text)

<RootWidget>:
    Label:
        id: first
        center_x: 100
        text: "text"

    SubWidget:
        id: second
        center_x: 200

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

My first idea was at least to store reference to first at root level and reference to it:

<SubWidget@RelativeLayout>:
    Label:
        text: str(root.parent.l.text)


<RootWidget>:
    l: first

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

    SubWidget:
        id: second
        center_x: 200

But this leads to exception:

AttributeError: 'NoneType' object has no attribute 'text'

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

So I have two questions:

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

回答1:

  1. The object property l probably gets populated after 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.

  2. 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:

BoxLayout

    Label
        id: label
        text: 'hello world'

    SubWidget
        label_text: label.text

<SubWidget@BoxLayout>
    label_text: 'none'

    Label
        text: root.label_text