Python KivyMD:如何使toggle_nav_drawer()函数起作用?

时间:2019-06-17 17:00:23

标签: python python-3.x kivy navigationbar kivy-language

我的kv代码有问题。我想用几个$newHours = explode('-',$hours); $time_am = date("H:i", strtotime($newHours[0])); $time_pm = date("H:i", strtotime($newHours[1])); 创建一个MDNavigationDrawer。窗口出现,但是当我单击MDToolbar时,程序崩溃并显示此错误消息。

NavigationDrawerIconButtons

我从一个单独的文件中导入了 kv代码

 Traceback (most recent call last):
   File "C:/Users/path/to/my/file/main.py", line 189, in <module>
     KivyGUI().run()
   File "C:\Users\uname\Anaconda3\lib\site-packages\kivy\app.py", line 855, in run
     runTouchApp()
   File "C:\Users\uname\Anaconda3\lib\site-packages\kivy\base.py", line 504, in runTouchApp
     EventLoop.window.mainloop()
   File "C:\Users\uname\Anaconda3\lib\site-packages\kivy\core\window\window_sdl2.py", line 746, in mainloop
     self._mainloop()
   File "C:\Users\uname\Anaconda3\lib\site-packages\kivy\core\window\window_sdl2.py", line 478, in _mainloop
     EventLoop.idle()
   File "C:\Users\uname\Anaconda3\lib\site-packages\kivy\base.py", line 342, in idle
     self.dispatch_input()
   File "C:\Users\uname\Anaconda3\lib\site-packages\kivy\base.py", line 327, in dispatch_input
     post_dispatch_input(*pop(0))
   File "C:\Users\uname\Anaconda3\lib\site-packages\kivy\base.py", line 293, in post_dispatch_input
     wid.dispatch('on_touch_up', me)
   File "kivy\_event.pyx", line 707, in kivy._event.EventDispatcher.dispatch
   File "C:\Users\uname\Anaconda3\lib\site-packages\kivymd\ripplebehavior.py", line 84, in on_touch_up
     return super().on_touch_up(touch)
   File "C:\Users\uname\Anaconda3\lib\site-packages\kivymd\button.py", line 480, in on_touch_up
     return super().on_touch_up(touch)
   File "C:\Users\uname\Anaconda3\lib\site-packages\kivy\uix\behaviors\button.py", line 179, in on_touch_up
     self.dispatch('on_release')
   File "kivy\_event.pyx", line 703, in kivy._event.EventDispatcher.dispatch
   File "kivy\_event.pyx", line 1214, in kivy._event.EventObservers.dispatch
   File "kivy\_event.pyx", line 1138, in kivy._event.EventObservers._dispatch
   File "C:\Users\path\to\my\file\design.kv", line 59, in <lambda>
     left_action_items: [['dots-vertical', lambda x: root.toggle_nav_drawer()]]
   File "kivy\weakproxy.pyx", line 32, in kivy.weakproxy.WeakProxy.__getattr__
 AttributeError: 'LayoutPy' object has no attribute 'toggle_nav_drawer'

Python代码:

#:kivy 1.11.0
#:import MDNavigationDrawer kivymd.navigationdrawer.MDNavigationDrawer
#:import NavigationLayout kivymd.navigationdrawer.NavigationLayout
#:import NavigationDrawerDivider kivymd.navigationdrawer.NavigationDrawerDivider
#:import NavigationDrawerToolbar kivymd.navigationdrawer.NavigationDrawerToolbar
#:import NavigationDrawerSubheader kivymd.navigationdrawer.NavigationDrawerSubheader
#:import MDToolbar kivymd.toolbar.MDToolbar

<ContentNavigationDrawer@MDNavigationDrawer>:
    drawer_logo: 'src/LinguIcon.png'

    NavigationDrawerSubheader:
        text: "Menu:"

<LayoutPy>:
    orientation: 'vertical'
    scr_mngr: scr_mngr

    NavigationLayout:
        id: nav_layout

        ContentNavigationDrawer:
            id: nav_drawer
            name: 'nav_drawer'

            NavigationDrawerToolbar:
                title: 'Options'

            NavigationDrawerIconButton:
                icon: 'settings'
                text: 'Select Language'
                on_release: root.open2ndScreen('screen_card')

            NavigationDrawerIconButton:
                icon: 'close'
                text: 'Exit'
                on_release: root.exit()

            NavigationDrawerIconButton:
                icon: 'face'
                text: 'Contact the developer'
                on_release: root.sendDevHint()

        BoxLayout:
            orientation: 'vertical'

            MDToolbar:
                id: toolbar
                title: 'Menu'
                md_bg_color: app.theme_cls.primary_color
                background_palette: 'Primary'
                background_hue: '500'
                left_action_items: [['dots-vertical', lambda x: root.toggle_nav_drawer()]]

            Widget:

    ScreenManager:
        id: scr_mngr
        screen_main: screen_main

        Screen:
            id: screen_main
            name: 'screen_main'
            input_words: input_words
            lbl: lbl
            btn: btn

            FloatLayout:

                ### A few widgets ### 

        Screen:
            id: screen_card
            name: 'screen_card'

            FloatLayout:

                ### A few widgets ###

削减了很多 Python代码,对您来说它更清晰了。我认为这不是模块本身的问题,因为KivyMD example code对我来说很好(这也是我运行该解决方案时的样子)。我认为问题在于我的import sys import kivy from kivy.app import App from kivy.uix.floatlayout import FloatLayout from kivy.uix.boxlayout import BoxLayout from kivy.core.window import Window from kivymd.theming import ThemeManager from kivymd.label import MDLabel from kivymd.textfields import MDTextField, MDTextFieldClear, MDTextFieldRect, MDTextFieldRound from kivy.lang import Builder from kivymd.navigationdrawer import MDNavigationDrawer, NavigationDrawerIconButton, NavigationLayout from kivy.properties import ObjectProperty from kivymd.toast import toast kivy.require('1.11.0') class LayoutPy(FloatLayout): def __init__(self, **kwargs): super(LayoutPy, self).__init__(**kwargs) self.scr_mngr = ObjectProperty(None) self.build_nav_btns() def callback(self, instance, value): toast("Pressed item menu %d" % value) def exit(self): sys.exit(1) def build_nav_btns(self): btns = ["Select Language", "Contact the developer", "Exit"] for count, btn in enumerate(btns): if count == 1: self.ids.nav_drawer.add_widget( NavigationDrawerIconButton( icon='settings', text=btn, on_release=lambda x, btn: self.callback(x, btn))) elif count == 2: self.ids.nav_drawer.add_widget( NavigationDrawerIconButton( icon='face', text=btn, on_release=lambda x, btn: self.callback(x, btn))) elif count == 3: self.ids.nav_drawer.add_widget( NavigationDrawerIconButton( icon='close', text=btn, on_release=lambda x: self.exit())) Builder.load_file("design.kv") class KivyGUI(App): theme_cls = ThemeManager() theme_cls.primary_palette = ("Teal") title = ("App") def build(self): c = LayoutPy() return c if __name__ == "__main__": KivyGUI().run() 类继承自LayoutPy对象,而该FloatLayout对象没有toggle_nav_drawer对象……但是我现在不知道如何在现有代码中实现合适的解决方案(我现在尝试了2天)。如果您需要整个代码(添加NavigationDrawer之前一切正常,则可以查看here

非常感谢!

1 个答案:

答案 0 :(得分:1)

错误-AttributeError

     left_action_items: [['dots-vertical', lambda x: root.toggle_nav_drawer()]]
   File "kivy\weakproxy.pyx", line 32, in kivy.weakproxy.WeakProxy.__getattr__
 AttributeError: 'LayoutPy' object has no attribute 'toggle_nav_drawer'

根本原因

对象LayoutPy不具有属性toggle_nav_drawer,因为toggle_nav_drawer是在NavigationLayout:的实例化子项LayoutPy中定义的。

解决方案

root.toggle_nav_drawer()替换为root.ids.nav_layout.toggle_nav_drawer()

摘要-kv文件

BoxLayout:
    orientation: 'vertical'

    MDToolbar:
        id: toolbar
        title: 'Menu'
        md_bg_color: app.theme_cls.primary_color
        background_palette: 'Primary'
        background_hue: '500'
        left_action_items: [['dots-vertical', lambda x: root.ids.nav_layout.toggle_nav_drawer()]]

输出

Result