具有多个屏幕的 KivyMD 菜单

Posted

技术标签:

【中文标题】具有多个屏幕的 KivyMD 菜单【英文标题】:KivyMD menu with multiple screens 【发布时间】:2021-02-26 07:24:45 【问题描述】:

我想使用带有多个屏幕的 KivyMD 菜单。在 KivyMD 的文档中,它只显示了如何使用 App Class 创建它。但是,我的目标是在具有多个屏幕的应用程序中使用菜单,这就是为什么我发布了一个具有两个屏幕的示例代码。当我运行此代码时,我收到错误消息:

caller=self.ids.drop_item,

文件“kivy\properties.pyx”,第 863 行,在 kivy.properties.ObservableDict.getattr

AttributeError: 'super' 对象没有属性 'getattr'

有人知道怎么解决吗?谢谢。

ma​​in.py

from kivy.core.window import Window
from kivy.uix.screenmanager import Screen, ScreenManager
from kivy.lang import Builder
from kivymd.app import MDApp
from kivymd.uix.menu import MDDropdownMenu
from kivy.properties import ObjectProperty


Window.size = (400, 800)


class FirstScreen(Screen):

    drop_item = ObjectProperty(None)

    def __init__(self, **kwargs):
        super().__init__(**kwargs)
        menu_items = ["icon": "git", "text": f"Item i" for i in range(5)]
        self.menu = MDDropdownMenu(
            caller=self.ids.drop_item,
            items=menu_items,
            callback=self.set_item,
            width_mult=4,
        )

    def set_item(self, instance_menu_item):
        self.ids.drop_item.text = instance_menu_item.text
        self.menu.dismiss()



class SecondScreen(Screen):
    pass

class WindowManager(ScreenManager):
    pass

GUI = Builder.load_file("main.kv")

class App(MDApp):

    def build(self):
        return GUI


if __name__ == "__main__":
    App().run()

ma​​in.kv

WindowManager:
    FirstScreen:
        name: 'firstscreen'
    SecondScreen:
        name: 'secondscreen'

<FirstScreen>:
    drop_item: drop_item
    BoxLayout:
        orientation: 'vertical'

        MDDropDownItem:
            id: drop_item
            pos_hint: 'center_x': .5, 'center_y': .5
            text: "Select"
            on_release: root.menu.open()

        Button:
            text: "Go to SecondScreen"
            on_press:
                app.root.current = "secondscreen"

<SecondScreen>:

    BoxLayout:
        orientation: 'vertical'

        Button:
            text: "Go to FirstScreen"
            on_press:
                app.root.current = "firstscreen"

【问题讨论】:

【参考方案1】:

您对self.ids.drop_item 的引用似乎是在ids 可用之前发生的。您可以通过使用Clock.schedule_once() 稍微延迟该访问来解决此问题。这是您的 FirstScreen 的修改版本:

class FirstScreen(Screen):

    drop_item = ObjectProperty(None)

    def __init__(self, **kwargs):
        super().__init__(**kwargs)
        Clock.schedule_once(self._post_init)

    def _post_init(self, dt):
        menu_items = ["icon": "git", "text": f"Item i" for i in range(5)]
        self.menu = MDDropdownMenu(
            caller=self.ids.drop_item,
            items=menu_items,
            callback=self.set_item,
            width_mult=4,
        )

    def set_item(self, instance_menu_item):
        self.ids.drop_item.text = instance_menu_item.text
        self.menu.dismiss()

我怀疑您需要将kv 文件的加载移动到App 内部:

# GUI = Builder.load_file("main.kv")

class App(MDApp):

    def build(self):
        GUI = Builder.load_file("main.kv")
        return GUI

【讨论】:

以上是关于具有多个屏幕的 KivyMD 菜单的主要内容,如果未能解决你的问题,请参考以下文章

如何在 kivymd 的单个屏幕中添加多个布局

下拉菜单 KivyMD 未打开

kivymd:如何在下拉菜单中添加图标?

kivyMD:如何使用工具栏操作项创建下拉菜单?

KivyMD 带有下拉菜单的文本字段

如何在 KivyMD、Python 中制作下拉菜单