【问题标题】:KivyMD KeyError on caller for MDDropdownMenuMDDropdownMenu 调用者上的 KivyMD KeyError
【发布时间】:2020-09-19 08:47:46
【问题描述】:

我正在尝试更改我现有的 Kivy 应用程序以包含漂亮的 KivyMD 小部件。我删除了MDRaisedButtonSpinneron_release callerMDDropdownMenu 以及已通过蓝牙与设备配对的设备名称列表(取决于平台)。对于这个测试示例,我只使用MDDropdownMenu docs 示例中所示的菜单项列表。

由于某种原因,我在初始化MDDropdownMenu 属性时收到KeyError: 'dev_button'MDRaisedButton id__init__ 方法在我的根类中,它位于名为 indexui.pyindexui.kv 的单独文件中,位于 main.pymain.kv 文件中。但是在main.py 文件中导入并包含在main.kv 文件中。该应用程序在更改 Spinner 之前确实运行了。

indexui.py

class RootLay(FloatLayout):
    this = ObjectProperty(None)  # App object
    bserial = ObjectProperty(None)  # Bluetooth variables starts
    recv_stream = ObjectProperty(None)
    send_stream = ObjectProperty(None)
    menu = ObjectProperty(None)
    rfsocket = ObjectProperty(None)
    device = ObjectProperty(None)
    pattern = ObjectProperty(None)
    def __init__(self, **kwargs):
        super().__init__(**kwargs)
        self.device = None
        self.pattern = re.compile(r'[GNSTUkg,\s]')
        self.dev_list = []
        menu_items = [{"icon": "git", "text": f"Item {i}"} for i in range(5)]
        print(dir(self.ids))
        self.menu = MDDropdownMenu(
            caller=self.ids.dev_button, items=menu_items, width_mult=4
        )
        self.menu.bind(on_release=self.menu_callback)

indexui.kv

<RootLay>:
    MDToolbar:
        pos_hint: {'top': 1, 'right': 1}
        title: "Bluetooth Weigh"
    MDRaisedButton:
        id: dev_button
        text: "SEE DEVICES"
        pos_hint: {'top': 0.76, 'right': 0.9}
        on_release: app.root.menu.open()

ma​​in.py

from kivymd.app import MDApp
from views.indexui import RootLay
from kivy.properties import ObjectProperty

class MainApp(MDApp):
    def build(self):
        self.theme_cls.primary_palette = "Yellow"  # "Purple", "Red"
        self.theme_cls.primary_hue = "600"
        # self.icon = 'bluetooth-connected_326502.png'
        root = ObjectProperty(RootLay())
        return root

    def on_pause(self):
        return True
    
MainApp().run()

ma​​in.kv

#:include views/indexui.kv

RootLay:

有人可以帮我理解为什么会有KeyError吗? MDRaisedButton 作为方法在 RootLay 类范围内。因此,我应该能够访问它的所有属性。

【问题讨论】:

  • 您的kv 似乎没有被加载。您是否明确加载了kv?你的kv 文件是main.kv吗?
  • 您好,感谢您的回复。是的,我相信它正在加载,因为 main.kv 文件与 App 类同名。我在上面添加了kv 文件代码。有什么我应该做的额外的吗?或者我没有正确导入的东西?

标签: python python-3.x kivy keyerror kivymd


【解决方案1】:

我认为问题在于您试图在 RootLay 类可用之前访问它们。我建议使用Clock.schedule_once() 来延迟访问,如下所示:

class RootLay(FloatLayout):
    this = ObjectProperty(None)  # App object
    bserial = ObjectProperty(None)  # Bluetooth variables starts
    recv_stream = ObjectProperty(None)
    send_stream = ObjectProperty(None)
    menu = ObjectProperty(None)
    rfsocket = ObjectProperty(None)
    device = ObjectProperty(None)
    pattern = ObjectProperty(None)
    def __init__(self, **kwargs):
        super().__init__(**kwargs)
        self.device = None
        self.pattern = re.compile(r'[GNSTUkg,\s]')
        self.dev_list = []
        Clock.schedule_once(self.setup_menu)  # delay until ids are available

    def setup_menu(self, dt):
        menu_items = [{"icon": "git", "text": f"Item {i}"} for i in range(5)]
        self.menu = MDDropdownMenu(
            caller=self.ids.dev_button,
            items=menu_items,
            width_mult=4
        )
        self.menu.bind(on_release=self.menu_callback)

【讨论】:

  • 这是一个非常聪明的解决方案。谢谢!
  • 如果你给menu_items添加了一个回调函数并且没有像我的例子那样绑定它,它会影响函数的工作吗?
  • menu_items=[{'callback': self.menu_callback, 'text': f"Item {i}"} for i in range(5)}],而不是将其绑定到self.menu
  • 我问的原因是因为 Erik Sandberg 以这种方式使用 callback 做了一个例子,但是当 callbackviewclass 设置为 items 时它不起作用钥匙。它仅在设置为MDDropdownMenu 实例上的callback 键时才有效。在MDDropdownMenu 源代码中,我也找不到可以在MDDropdownMenu 实例的items 键上设置的viewclasscallback。所以也许它已经被弃用了,
  • 我不知道在items 列表中包含回调的任何方法,但是,您可以将callback=self.menu_callback 添加到MDDropdownMenu() 调用(并删除self.menu.bind 调用)。
猜你喜欢
  • 2021-01-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-02-21
  • 1970-01-01
  • 1970-01-01
  • 2021-10-06
相关资源
最近更新 更多