NumesSanguis
NumesSanguis

Reputation: 6342

Kivy class in .py and .kv interaction

I'm not fully grasping how classes in a python file and the kivy language interact. I'm currently modifying the Showcase example of Kivy to increase my understanding.

File structure

main.py

class Testy(BoxLayout):
    ttext = 'Bla'
    #other code

class ShowcaseScreen(Screen):
    fullscreen = BooleanProperty(False)

    def add_widget(self, *args):
        if 'content' in self.ids:
            return self.ids.content.add_widget(*args)
        return super(ShowcaseScreen, self).add_widget(*args)


class ShowcaseApp(App):
    #code

test.kv

<Testy>:
    orientation: 'vertical'

    Label:
        text: root.ttext

ShowcaseScreen:
    name: 'LearnKanji'
    fullscreen: True
    #Some ref to <Testy>

Question

I want to have my code in Testy(), because I'm planning to write a lot of code aimed at what happens in that single screen and I don't want to clutter ShowcaseScreen(), because ShowcaseScreen is also meant for other screens.

To clarify, in test.kv I'm referring to the variable ttext. If I didn't make the class Testy() I would have put it as follows:

ShowcaseScreen:
    name: 'LearnKanji'
    fullscreen: True
    BoxLayout:
        text: root.ttext

And then in main.py I would need to put

class ShowcaseScreen(Screen):
    ttext = 'Bla'

However since many screens besides Testy use the class ShowcaseScreen(), putting all the code for all screens in here would make it too much of a mess. Therefore I want the code per screen in a separate class. I think this is a better way for bigger code projects.

So how do I refer to after calling ShowcaseScreen: in the test.kv file? So that I can put the code meant for Testy in Testy() and keep my files and classes more organized.

Follow up question: Kivy class in .py and .kv interaction 2

Upvotes: 3

Views: 1600

Answers (1)

Totem
Totem

Reputation: 7369

You can use the ScreenManager. Have a look here, I changed some of your code to provide an example of using the ScreenManager to seperate out the code for each screen into their own classes. If there are problems with this let me know.

main.py:

from kivy.app import App
from kivy.uix.screenmanager import ScreenManager, Screen, FadeTransition
from kivy.properties import ObjectProperty


class Testy(Screen):

    ttext = 'Screen 2'
    #other code

class ScreenTwo(Screen):
    pass

class Manager(ScreenManager):

    testy = ObjectProperty(None)
    screen_2 = ObjectProperty(None)


class ShowcaseApp(App):

    def build(self):
        return Manager(transition=FadeTransition())

if __name__ == "__main__":
    ShowcaseApp().run()

kv file:

<Testy>:
    BoxLayout:
        Button:
            text: root.ttext
            on_press: root.manager.current = "screen_two"

<ScreenTwo>:
    BoxLayout:
        Button:
            text: "Screen 1"
            on_press: root.manager.current = "testy_screen"


<Manager>:
    id: screen_manager

    testy: testy
    screen_2: screen_2

    Testy:
        id: testy
        name: 'testy_screen'
        manager: screen_manager

    ScreenTwo:
        id: screen_2
        name: 'screen_two'
        manager: screen_manager

Upvotes: 1

Related Questions