Insert a piece of code in the text of a Label that involves variables inside kv lang

Viewed 48

I need to insert a piece of code in the text of a Label that involves variables inside kv lang as shown below:

import kivy
from kivy.app import App
from kivy.uix.widget import Widget
from kivy.lang.builder import Builder
from kivy.core.window import Window

Window.size=(200,200)

Builder.load_string("""
<Screen>
    BoxLayout:
        orientation:'vertical'
        size:root.width,root.height
        Label:
            id:label
            text:'Nothing'
        Button:
            id:button
            text:'Insert'
            on_release: root.insert_text()
""")

class Screen(Widget):
    def insert_text(self):
        self.ids.label.text='Something' if button.text=='Insert' else 'Nothing' #Label should say "Something" if Button's text says 'Insert'
class App(App):
    def build(self):
        return Screen()

if __name__=='__main__':
    App().run()

When running this code I get the error: NameError: name 'button' is not defined

How can I avoid this error and have the entered code work within kv lang? I already tried putting self.ids.button.text instead of button.text and despite not getting the error, it doesn't work inside the application either.

Edit: Also tried insert button.text as a raw string but kv lang just ignored it.

2 Answers

Since the error is name 'button' is not defined, you just need to define button. Like this:

def insert_text(self):
    button = self.ids.button  # define button
    self.ids.label.text='Something' if button.text=='Insert' else 'Nothing' #Label should say "Something" if Button's text says 'Insert'

If you want Label text to change without a Button press, then you probably want to use a Property. You can reference a Property in kv and any changes to that Property will trigger evaluation where that Property is used. So, here is a modified version of your code that uses a Property named follow_changes that controls whether the Label text follows the Button text:

from kivy.app import App
from kivy.properties import BooleanProperty
from kivy.uix.widget import Widget
from kivy.lang.builder import Builder
from kivy.core.window import Window

Window.size = (200, 200)

Builder.load_string("""
<Screen>
    BoxLayout:
        orientation:'vertical'
        size:root.width,root.height
        Label:
            id:label
            text: 'Something' if root.follow_changes and button.text == 'Insert' else 'Nothing'  # use follow_changes Property
        Button:
            id:button
            text:'Insert'
            on_release:
                root.follow_changes = True  # turn on following_changes
        Button:
            text: "Change Button Text"
            on_release:
                button.text = 'Abba'
""")

class Screen(Widget):
    follow_changes = BooleanProperty(False)  # Property to control Label text

class App(App):
    def build(self):
        return Screen()

if __name__=='__main__':
    App().run()
Related