KivyMD 多屏菜单
KivyMD menu with multiple screens
我想使用多屏幕的 KivyMD 菜单。在 KivyMD 的文档中,它只显示了如何使用 App Class 创建它。但是,我的目标是在具有多个屏幕的应用程序中使用菜单,这就是我发布具有两个屏幕的示例代码的原因。当我 运行 此代码时,我收到错误消息:
来电者=self.ids.drop_item,
文件“kivy\properties.pyx”,第 863 行,在 kivy.properties.ObservableDict.getattr
AttributeError: 'super' 对象没有属性 'getattr'
有人知道怎么解决吗?谢谢。
main.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()
main.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"
您对 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 的文档中,它只显示了如何使用 App Class 创建它。但是,我的目标是在具有多个屏幕的应用程序中使用菜单,这就是我发布具有两个屏幕的示例代码的原因。当我 运行 此代码时,我收到错误消息:
来电者=self.ids.drop_item,
文件“kivy\properties.pyx”,第 863 行,在 kivy.properties.ObservableDict.getattr
AttributeError: 'super' 对象没有属性 'getattr'
有人知道怎么解决吗?谢谢。
main.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()
main.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"
您对 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