Kivy - 如何访问由 .kv 文件创建的类的实例?

Posted

技术标签:

【中文标题】Kivy - 如何访问由 .kv 文件创建的类的实例?【英文标题】:Kivy - How to access instance of class created by .kv file? 【发布时间】:2021-06-24 08:37:31 【问题描述】:

我的 OrderManagementScreen 类首先由 Builder.load_file 实例化,然后由 sm.add_widget(OrderManagementScreen(name='order_management')) 实例化。

我希望能够访问由 Builder.load_file 创建的实例 - 我该怎么做?

This post 是我能找到的最接近的,但是当我执行 MDApp.get_running_app().root 时它返回 None。

app.py:(我的 update_database 函数中的各种尝试)

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.

ma​​in.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

【问题讨论】:

【参考方案1】:

我想这表明有时你只需要离开电脑,然后以全新的眼光回来......

我的解决方案是在运行时简单地存储应用程序的实例,以便当我调用我的 update_database 函数时正在查看正确的实例 - 因此可以访问 kivy 创建的屏幕类的实例:

self.root.children[0].manager.get_screen('order_management')

我在这里使用 children[0],因为这是我添加到 ScreenManager 的第一个屏幕,'order_management' 显然是屏幕的名称。

我希望这偶然会对其他人有所帮助。

新的 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.

【讨论】:

以上是关于Kivy - 如何访问由 .kv 文件创建的类的实例?的主要内容,如果未能解决你的问题,请参考以下文章

如何访问由 Kivy 代码发起的类实例?

如何从 kivy 文件 (.kv) 访问不同类的 id/widget?

使用 Kivy 的时钟从 kivy 文件 (.kv) 访问不同类的 id/widget?

如何使用 kv 文件刷新 Kivy 中的 GridLayout

如何:main.py,带有 kivy 轮播代码的新类,kv 文件

如何在 KivyMD 的 .kv 文件中使用 kivy 中的数据表?