【问题标题】:KivyMD Layout - Add widget (from python) to existing BoxLayoutKivyMD Layout - 将小部件(来自 python)添加到现有的 BoxLayout
【发布时间】:2021-03-24 21:47:36
【问题描述】:

我花了很多时间在谷歌上搜索可能很简单的问题,但我绝对不知道哪里有问题......

我有简单的 primaryscreen.kv 文件,其中包含代码:

<ContentArea@MDBoxLayout>

<BottomBar@MDBoxLayout>

<PrimaryScreen>
    name: 'primary'
    id: primaryscreen

    content_area: content_area

    MDBoxLayout:

        spacing: 6
        padding: [10, 4, 10, 4]

        orientation: 'vertical'
        MDBoxLayout:
            size_hint_y: 1.2

            MDLabel:
                font_style: 'H5'
                text: root.app_title


        MDBoxLayout:
            size_hint_y: 5
            orientation: "horizontal"

            DevicesGrid:
                size_hint_x: 1


            ContentArea:
                id: content_area

                size_hint_x: 3
                orientation: "vertical"
...
...

还有primaryscreen.py文件:

...
...
with open(os.path.join(os.getcwd(),
                       "uix",
                       "screens",
                       "kv",
                       "primaryscreen.kv"), encoding="utf-8") as KV:
    Builder.load_string(KV.read())


class PrimaryScreen(MDScreen):
    def __init__(self, **kwargs):
        super(PrimaryScreen, self).__init__(**kwargs)

        self.app_title = "DeviceName"

        self.content_area.add_widget((MDLabel(text='aaaa')))

更新(在 mainscreen.kv 和 mainscreen.py 文件中添加目录树和代码)

├── main.py
└── uix
    ├── __init__.py
    └── screens
        ├── __init__.py
        ├── baseclass
        │   ├── __init__.py
        │   ├── mainscreen.py
        │   ├── primaryscreen.py
        │   └── settingsscreen.py
        └── kv
            ├── __init__.py
            ├── mainscreen.kv
            ├── primaryscreen.kv
            └── settingsscreen.kv

mainscreen.kv

<ScreenManagement>:
    id: sm
    PrimaryScreen:
        name: 'primary'
        id: primaryscreen
    SettingsScreen:
        name: 'settings'
        id: settingsscreen

mainscreen.py

with open(os.path.join(os.getcwd(),
                       "uix",
                       "screens",
                       "kv",
                       "mainscreen.kv"), encoding="utf-8") as KV:
    Builder.load_string(KV.read())


class MainScreen(ScreenManager):
    pass

我不知道我可以将我的自定义小部件(在本例中为它的 MDLabel)添加到现有的 BoxLayout。

请问,这可能吗?怎么样?

我尝试了很多组合(ids、ObjectProperties、MDApp.get_running_app().root)但没有成功:/

感谢您的任何想法...

工作解决方案(但我不知道是否是明确的解决方案/最佳实践):

我的文件 primaryscreen.py 已更新为:


class PrimaryScreen(MDScreen):
    def __init__(self, **kwargs):
        super(PrimaryScreen, self).__init__(**kwargs)

        Clock.schedule_once(self.update_screen)                    # <-- Added line

        self.app_title = "DeviceName"

    def update_screen(self, *args):                                # <-- Added line
        self.content_area.add_widget((MDLabel(text='aaaa',         # <-- Added line
                                              font_style='H3')))   # <-- Added line


【问题讨论】:

  • 您要添加哪个小部件?
  • Hello @DYD 在这种情况下,我想将 *.py 文件中创建的小部件“MDLabel”添加到 *.kv 文件中创建的小部件 ContentArea
  • 对不起,我不完全理解你的问题。你想达到什么目标?标签不能只添加到适当的 KV 文件中吗?还是必须在 .py 文件中?
  • @jda5 感谢您的关注。我的目标是动态地将 Python 文件中的 MDLabel 小部件添加到 *.kv 文件中。当我尝试Clock.schedule_once(self.update_screen) 时,它工作正常(更新的代码已添加到我的帖子底部)但我不知道这是否是一个明确的解决方案。

标签: python kivy kivy-language kivymd


【解决方案1】:

尝试使用on_enteron_pre_enter 事件(请参阅https://kivy.org/doc/stable/api-kivy.uix.screenmanager.html

我建议尝试以下方法:

class PrimaryScreen(MDScreen):

    def __init__(self, **kwargs):
        super(PrimaryScreen, self).__init__(**kwargs)
        self.app_title = "DeviceName"

    def on_pre_enter(self, text: str):
         self.content_area.add_widget((MDLabel(text=text, font_style='H3')))

如果失败,请尝试on_enter

您可以通过创建一个添加标签然后在on_pre_enter 中调用的函数来扩展它,即

class PrimaryScreen(MDScreen):

    def __init__(self, **kwargs):
        super(PrimaryScreen, self).__init__(**kwargs)
        self.app_title = "DeviceName"

    def on_pre_enter(self):
         self.add_label('aaaa')

    def add_label(self, text: str):
         self.content_area.add_widget((MDLabel(text=text, font_style='H3')))

现在您可以添加任意数量的标签!

这有帮助吗?

【讨论】:

  • 感谢您的支持。当我尝试您的第二部分(def on_pre_enter ... + def add_label ...)时,终端显示错误self.content_area.add_widget((MDLabel(text='text', font_style='H3'))) AttributeError: 'PrimaryScreen' object has no attribute 'content_area'。这个错误出现在我最后一次尝试中,之后我创建了这个问题。拜托,您认为问题可能出在我的“更大”应用程序结构上,或者为什么我的PrimaryScreen' object has no attribute 'content_area' 上?
  • 你可以试试self.ids['content_area']。尝试使用 children 属性访问它失败
  • 我看到了不同类型的错误self.ids['content_area'].add_widget((MDLabel(text=text, font_style='H3'))) KeyError: 'content_area'。但是与 Clock.schedule_once(self.update_screen) 相同的 *.kv 代码可以正常工作(完整代码在我的问题中)。你不觉得我有复杂的应用程序结构或多个 *.kv 文件的问题吗?
猜你喜欢
  • 2021-04-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-08-24
  • 1970-01-01
相关资源
最近更新 更多