Home > Back-end >  In Kivy.kv file how do I reference a method in another class
In Kivy.kv file how do I reference a method in another class

Time:10-17

I'm having difficulties understanding the relationship between kivy.kv files and class. I've coded a simple app with two classes, Test3App & Restore, with two Buttons and a Label. On clicking the Restore button I get error: AttributeError: 'Test3App' object has no attribute 'Restore'. My question is: How do I reference the Restore class in the kv or python files?

test3.py

from kivy.app import App

class Test3App(App): 

    def enlarge_text(self):
        if self.root.ids.label.font_size <90:
            self.root.ids.label.font_size  = 16
        else:
            self.root.ids.but1.text = ' font_size at\n[b][size=20]Maximum'
            self.root.ids.but1.color = 'yellow'

class Restore():

    def font_size_reset(self):
        self.root.ids.label.font_size = 16
        self.root.ids.but1.text = 'font_size\nEnlarge'
        self.root.ids.but1.color = 'white'

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

test3.kv

BoxLayout:

    Button:
        id: but1
        text: 'font_size\nEnlarge'
        on_press: app.enlarge_text()
        markup: True
  
    Button:
        text: 'font_size\nRestore'
        on_press: app.Restore.font_size_reset() 
  
    Label:
        id: label
        font_size: 16
        text: str(int(label.font_size))

CodePudding user response:

Typically, you would have an instance of Restore somewhere in your app, and you would reference that instance in your kv. Here is one way to access the font_size_reset() method in your kv:

#: import Restore test3.Restore
BoxLayout:

    Button:
        id: but1
        text: 'font_size\nEnlarge'
        on_press: app.enlarge_text()
        markup: True

    Button:
        text: 'font_size\nRestore'
        on_press: Restore.font_size_reset('Abba')

    Label:
        id: label
        font_size: 16
        text: str(int(label.font_size))

The import makes the Restore class available in the kv. The call to font_size_reset() provides a meaningless argument since that method requires a self (but doesn't use it). For this to work, the font_size_reset() method must be redefined to access the root widget of the app:

class Restore():

    def font_size_reset(self):
        root = App.get_running_app().root  # get a reference to the app root widget
        root.ids.label.font_size = 16
        root.ids.but1.text = 'font_size\nEnlarge'
        root.ids.but1.color = 'white'

A slightly better approach would be to make the font_size_reset() method static, so that the meaningless argument is not needed. In this approach, the Restore class can be:

class Restore():
    @staticmethod
    def font_size_reset():
        root = App.get_running_app().root  # get a reference to the app root widget
        root.ids.label.font_size = 16
        root.ids.but1.text = 'font_size\nEnlarge'
        root.ids.but1.color = 'white'

and the corresponding test3.kv:

#: import Restore test3.Restore
BoxLayout:

    Button:
        id: but1
        text: 'font_size\nEnlarge'
        on_press: app.enlarge_text()
        markup: True

    Button:
        text: 'font_size\nRestore'
        on_press: Restore.font_size_reset()

    Label:
        id: label
        font_size: 16
        text: str(int(label.font_size))
  • Related