Search code examples
kivykivy-language

How to Set Text for Label Nested in Another Widget (no python code)


I am trying to create a generic header class in .kv file and to set its text from another class, but I am unable to find any docs on how to do this. A sample of the code I am trying out is:

NestedLabel.kv:

#:kivy 2.0.0

<MyWidgetOne@Label>:
    text: "Widget One"

<MyWidgetTwo@Label>:
    text: "Widget Two"

<Header@BoxLayout>:
    # class to reuse over multiple views
    the_label: id_label
    size_hint: 1, None
    height: dp(40)
    canvas:
        Color:
            rgba: 1, 0, 0, 1
        Rectangle:
            size: self.size
            pos: self.pos
    Label:
        id: id_label
        text: "---headertext---"   # * want to set this generic text
        bold: True

<ViewOne>:
    BoxLayout:
        orientation: "vertical"
        Header:
            the_label: "ViewOneHeader"   # how to set * (above) from here?
            # the_label:
            #      text: "ViewOneHeader"        # not working
            # the_label.text: "ViewOneHeader"   # also not working
            # text: "ViewOneHeader"             # still not working
        MyWidgetOne:
        MyWidgetTwo:

NestedLabel.py:

from kivy.app import App
from kivy.uix.screenmanager import Screen

class ViewOne(Screen):
    pass

class NestedLabelApp(App):
    def build(self):
        self.root = root = ViewOne()
        return root

NestedLabelApp().run()

Screenshot: enter image description here The red header shows ---headertext---; I am trying to set it to ViewOneHeader. Appreciate any tips.


Solution

  • You can set a Property in the Header class by adding:

    header_text: "default"
    

    to the Header rule in kv. Then use it to set the Label text:

    text: root.header_text  # * want to set this generic text
    

    That property can then be set in any kv rule that creates a Header by setting:

    header_text: "This is the Header"
    

    Here is a modified version of your kv that does the above:

    #:kivy 2.0.0
    
    <MyWidgetOne@Label>:
        text: "Widget One"
    
    <MyWidgetTwo@Label>:
        text: "Widget Two"
    
    <Header@BoxLayout>:
        # class to reuse over multiple views
        header_text: "default"  # creates a property
        the_label: id_label
        size_hint: 1, None
        height: dp(40)
        canvas:
            Color:
                rgba: 1, 0, 0, 1
            Rectangle:
                size: self.size
                pos: self.pos
        Label:
            id: id_label
            text: root.header_text  # use the created property here
            bold: True
    
    <ViewOne>:
        BoxLayout:
            orientation: "vertical"
            Header:
                header_text: "This is the Header"  # set the desired value of the new property
            MyWidgetOne:
            MyWidgetTwo: