Reputation: 306
My class OrderManagementScreen is firstly instantiated by Builder.load_file and then by sm.add_widget(OrderManagementScreen(name='order_management')).
I would like to be able to access the instance created by Builder.load_file - how can I do this?
This post is the closest I could find, but when I do MDApp.get_running_app().root it returns None.
app.py: (mixture of attempts in my update_database function)
import atexit
from kivymd.app import MDApp
from kivy.lang import Builder
from kivy.uix.screenmanager import Screen, ScreenManager
from order_management.constants import HELP_TEXT
from order_management.presentation.order_management.order_management_view import OrderManagementScreen
from order_management.presentation.components.dialog import Dialog
from order_management.data.query import Query
class App(MDApp):
def __init__(self, **kwargs):
super().__init__(**kwargs)
self.screen = Builder.load_file(
"order_management/presentation/main.kv")
self._query = Query()
something = MDApp.get_running_app()
self._dialog = Dialog()
def build(self):
self.theme_cls.primary_palette = "Green"
sm = ScreenManager()
# Instantiates OrderManagementScreen.py
sm.add_widget(OrderManagementScreen(name='order_management'))
return self.screen
def handle_menu_click(self):
self._dialog.render_dialog("Usage Guide:", HELP_TEXT, None, None)
def update_database(self):
# order_management_screen = MDApp.get_running_app().screen.children[0].manager.get_screen('order_management')
# order_management_screen = self.screen.get_screen('order_management')
self.order_management_screen.update_database()
if __name__ == "__main__":
App().run()
main_app = App()
atexit.register(main_app.update_database) # Calls update_database on exit.
main.kv:
#:kivy 1.11.0
#:include order_management/presentation/order_management/order_management_ui.kv
# Having to use v1.11.0 because of bug relating to MDDataTable
<Toolbar@AnchorLayout>:
AnchorLayout:
anchor_x: 'center'
anchor_y: 'top'
MDToolbar:
title: 'Order Management App'
specific_text_color: app.theme_cls.accent_color
right_action_items: [['help-circle', lambda x: app.handle_menu_click()]]
elevation: 9
ScreenManager:
OrderManagementScreen:
Toolbar:
order_management_ui.kv:
#:kivy 1.11.0
# Having to use v1.11.0 because of bug relating to MDDataTable
<OrderManagementScreen>:
name: 'order_management'
id: order_management
GridLayout:
cols: 1
pos_hint: {'top': 0.85}
ScrollView:
id: table_container
Upvotes: 3
Views: 1151
Reputation: 306
I guess it goes to show how sometimes you just need to step away from the computer and come back with fresh eyes...
My solution was to simply store the instance of app when run so that when I called my update_database function is was looking at the correct instance - and therefore could access the instance of a screen class the kivy had created with:
self.root.children[0].manager.get_screen('order_management')
I use children[0] here because this is the first screen I added to ScreenManager, and 'order_management' is the name of the screen obviously.
I hope that this by chance does help someone else.
New app.py:
import atexit
from kivymd.app import MDApp
from kivy.lang import Builder
from kivy.uix.screenmanager import Screen, ScreenManager
from order_management.constants import HELP_TEXT
from order_management.presentation.order_management.order_management_view import OrderManagementScreen
from order_management.presentation.components.dialog import Dialog
from order_management.data.query import Query
class App(MDApp):
def __init__(self, **kwargs):
super().__init__(**kwargs)
self.screen = Builder.load_file(
"order_management/presentation/main.kv")
self._query = Query()
self._dialog = Dialog()
def build(self):
self.theme_cls.primary_palette = "Green"
sm = ScreenManager()
sm.add_widget(OrderManagementScreen(name='order_management'))
return self.screen
def handle_menu_click(self):
self._dialog.render_dialog("Usage Guide:", HELP_TEXT, None, None)
def update_database(self):
order_management_screen = self.root.children[0].manager.get_screen('order_management')
order_management_screen.update_database()
if __name__ == "__main__":
app = App()
app.run()
atexit.register(app.update_database) # Calls update_database on exit.
Upvotes: 1