Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python / Kivy: conditional design in .kv file

Would an approach similar to the example below be possible in Kivy?
The code posted obviously doesn't work, and again it's only an example: I will need different layouts to be drawn depending on a certain property.

How would you suggest working this out?

BoxLayout:
    number: 0
    if self.number > 3:
        Label:
            text: 'number is bigger than 3'
        Button:
            text: 'click here to decrease'
            on_press: root.number -= 1
    else:
        Label:
            text: 'number is smaller than 3'
        Button:
            text: 'click here to increase'
            on_press: root.number += 1
like image 567
nxet Avatar asked Dec 17 '16 17:12

nxet


2 Answers

KV lang has only a limited functionality, so if you want more control you should put your logic in the Python code. For example you can move your layouts into separate widgets and then dynamically select proper one from Python code with add_widget() and remove_widget().

from kivy.app import App
from kivy.uix.boxlayout import BoxLayout
from kivy.properties import NumericProperty
from kivy.lang import Builder

Builder.load_string('''
<SubWidget1>:
    Label:
        text: 'number is bigger than 3'
    Button:
        text: 'click here to decrease'
        on_press: root.parent.number -= 1

<SubWidget2>:
    Label:
        text: 'number is smaller than 3'
    Button:
        text: 'click here to increase'
        on_press: root.parent.number += 1

<MyWidget>
    number: 0
''')

class SubWidget1(BoxLayout):
    pass

class SubWidget2(BoxLayout):
    pass

class MyWidget(BoxLayout):
    number = NumericProperty()

    def __init__(self, *args):
        super(MyWidget, self).__init__(*args)
        self.widget = None
        self._create_widget()

    def _create_widget(self):
        print(self.number)
        if self.widget is not None:
            self.remove_widget(self.widget)
        if self.number > 3:
            self.widget = SubWidget1()
        else:
            self.widget = SubWidget2()
        self.add_widget(self.widget)

    def on_number(self, obj, value):
        self._create_widget()

class MyApp(App):
    def build(self):
        return MyWidget()

if __name__ == '__main__':
    MyApp().run()
like image 176
Nykakin Avatar answered Sep 27 '22 23:09

Nykakin


I would go with ScreenManager or a Carousel, a simple example might be:

Carousel: 
    index: 1# or a "certain property" :)
    scroll_timeout: 0.0 # disable the user ability to mess with the widgets layout 
    BoxLayout: #first option
        Label:
        Button:
    BoxLayout: #2nd option
        Button:
        Label:

If you'll bind index to a property of your choice it will automatically switch the layout :)...

A ScreenManager based approach will be quite similar, the major change is only binding the current_screen property instead of index

like image 25
Yoav Glazner Avatar answered Sep 27 '22 22:09

Yoav Glazner