randy
randy

Reputation: 53

Direct translation from kv lang to Python

I am trying to understand the kv lang by writing the equivalent in purely Python. My attempt at direct translating the kivy lang to Python failed miserably. The programs look and behave completely differently!

Here is the code using kv lang:

from kivy.app import App
from kivy.lang import Builder
from kivy.uix.widget import Widget
from kivy.properties import StringProperty

import random

Builder.load_string( '''
<YourWidget>:
    BoxLayout:
        size: root.size
        Button:
            text: "Change text"
            on_release: root.change_text()
        Label:
            text: root.random_number
''')

class YourWidget(Widget):
    random_number = StringProperty()

    def __init__(self, **kwargs):
        super(YourWidget, self).__init__(**kwargs)
        self.random_number = str(random.randint(1, 100))

    def change_text(self):
        self.random_number = str(random.randint(1, 100))

class YourApp(App):
    def build(self):
        return YourWidget()

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

And here is the code without kv lang:

from kivy.app import App
from kivy.lang import Builder
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.button import Button
from kivy.uix.label import Label
from kivy.uix.widget import Widget
from kivy.properties import StringProperty

import random

class YourWidget(Widget):
    random_number = StringProperty('')

    def __init__(self, **kwargs):
        super(YourWidget, self).__init__(**kwargs)

        # box layout
        box = BoxLayout(size = self.size)
        self.add_widget(box)

        # button widget
        btn = Button(text='Change text', on_release=self.change_text)
        box.add_widget(btn)

        # label widget
        self.random_number = str(random.randint(1, 100))
        lbl = Label(text=self.random_number)
        box.add_widget(lbl)

    def change_text(self, instance):
        self.random_number = str(random.randint(1, 100))

class YourApp(App):
    def build(self):
        return YourWidget()

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

Firstly, the main widget (YourWidget) in the pure Python program is not the same size as the window, compared to the kv lang program.

Secondly, the label text does not get modified whenever I press the button unlike in the kv lang program.

Would someone show me what would be a correct 'translation' of the kivy lang for this program?

Upvotes: 1

Views: 696

Answers (1)

inclement
inclement

Reputation: 29468

box = BoxLayout(size = self.size)

In Python, accessing attributes captures their current value and nothing else, whereas kv automatically detects that a value is a property and creates a binding to update when it changes. You therefore have to create your own binding. In cases like this, you can use

self.bind(size=box.setter('size'))

Upvotes: 1

Related Questions