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))