Python KivyMD:如何使toggle_nav_drawer()函数起作用? [英] Python KivyMD: How can I make the toggle_nav_drawer() function work?

查看:89
本文介绍了Python KivyMD:如何使toggle_nav_drawer()函数起作用?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的kv代码在这里有问题.我想用几个NavigationDrawerIconButtons创建一个MDNavigationDrawer.窗口出现,但是当我单击MDToolbar时,程序崩溃并显示此错误消息.

I got a problem with my kv code here. I want to create a MDNavigationDrawer with a few NavigationDrawerIconButtons. The window shows up but when I click at the MDToolbar the program crashes and shows this Error Message.

 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'

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

I import the kv code from a separate file.

#: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代码:

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()

削减了很多 Python代码,对您来说它更加清晰了.我不认为这是模块本身的问题,因为 KivyMD示例代码对我来说很好(这也是我运行该解决方案时的样子).我认为问题是我的LayoutPy类从没有toggle_nav_drawer对象的FloatLayout继承...但是现在我不知道如何在现有代码中实现合适的解决方案(我尝试了2天现在).如果您需要整个代码(添加NavigationDrawer之前一切都可以正常工作),则可以看看

I cut a lot of Python code so it is a bit more clear for you. I don't think that it is a problem with the module itself because the KivyMD example code works fine for me (Thats also what the solution should look like when I run it). I think the problem is that my LayoutPy class inherits from FloatLayout which has no toggle_nav_drawer object... but I have no idea now how I could implement a suitable solution into my existing code (I am trying for 2 days now). If you need the whole code (everything almost worked fine before adding the NavigationDrawer) you can take a look here.

非常感谢!

推荐答案

错误-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是在LayoutPy的实例化子级NavigationLayout:中定义的.

Root Cause

The object, LayoutPy does not has an attribute toggle_nav_drawer because the toggle_nav_drawer is defined in the instantiated child, NavigationLayout: of LayoutPy.

root.ids.nav_layout.toggle_nav_drawer()

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()]]

输出

这篇关于Python KivyMD:如何使toggle_nav_drawer()函数起作用?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆