简体   繁体   中英

Create an expansion panel in / on a new screen using kivymd and python

I have created code with 2 screens and need one of them to have an expansion panel. Unfortunately I can't get the panel to show up with the content inside of it. Instead I'm stuck with chaos in my head and a side of migraine, so here is my code, an example of what I want it to look like and what I managed to create minus my full code.

Video example: https://www.kapwing.com/videos/62f4074bafd00100c829b84c

Video example of problem: https://www.kapwing.com/videos/62f41c828f6acd00521caae1

As shown in the video example:

1st code:

from kivy.lang import Builder
from kivymd.app import MDApp
from kivy.uix.screenmanager import Screen
from kivymd.uix.expansionpanel import MDExpansionPanel
from kivymd.uix.expansionpanel import MDExpansionPanelOneLine
from kivymd.uix.boxlayout import MDBoxLayout

KV = '''
MDScreen:

    MDNavigationLayout:

        ScreenManager:
            id: manager

            MDScreen:
                name: 'Home'

                AnchorLayout:
                    anchor_x: "center"
                    anchor_y: "top"
                    MDToolbar:
                        md_bg_color: 0, 0, 0, 0.5
                        title: "Example"
                        elevation: 10
                        left_action_items: [["menu", lambda x: mud_list.set_state("open")]]
                        right_action_items: [["dots-vertical", lambda x:app.dropdown(x)]]

                MDNavigationDrawer:
                    id: mud_list

                    BoxLayout:
                        orientation: 'vertical'
                        spacing: '5dp'
                        padding: '5dp'

                        ScrollView:
                            MDList:
                                OneLineIconListItem:
                                    text: '[Settings]'
                                    on_release:
                                        manager.current = 'Settings'
                                        root.ids.mud_list.set_state(new_state='toggle', animation=True)
                                    divider: None
                                    IconLeftWidget:
                                        icon: 'cog'
                                        on_release:
                                            manager.current = 'Settings'
                                            root.ids.mud_list.set_state(new_state='toggle', animation=True)       

                        MDLabel:
                            text:' By Author'
                            size_hint_y: None
                            font_style: 'Button'
                            height: self.texture_size[1]

            MDScreen:
                name: 'Settings'

                AnchorLayout:
                    anchor_x: "center"
                    anchor_y: "top"

                    MDToolbar:
                        id: mdt_color
                        md_bg_color: 1, 1, 1, 1
                        elevation: 10

                MDIconButton: 
                    icon: "keyboard-backspace"
                    pos_hint: {"center_x": 0.09, "center_y": 0.945}
                    on_release: manager.current = 'Home'

                MDBoxLayout:
                    size_hint: 1, 0.89
                    orientation : 'vertical'    
                    ScrollView:
                        MDBoxLayout:
                            orientation:'vertical'
                            adaptive_height: True
                            padding:[dp(15),dp(15),dp(15),dp(35)]
                            spacing:dp(15)

                            Content
                                adaptive_height: True
                                orientation: 'vertical'

                                OneLineIconListItem:
                                    text: "Dark"
                                    on_release:app.theme_changer2()
                                    divider: None
                                    IconLeftWidget:
                                        icon: 'weather-night'
                                        on_release:app.theme_changer2()

                                OneLineIconListItem:
                                    text: "Light"
                                    on_release:app.theme_changer()
                                    divider: None
                                    IconLeftWidget:
                                        icon: 'white-balance-sunny'
                                        on_release:app.theme_changer()

                            ScrollView:
                                MDGridLayout:
                                    id: box
                                    cols: 1
                                    adaptive_height: True
'''


class Content(MDBoxLayout):
    """Custom content."""

    def __draw_shadow__(self, origin, end, context=None):
        pass


class MainApp(MDApp):
    def __init__(self, **kwargs):
        super().__init__(**kwargs)
        self.menu = None
        self.menu_list = None
        self.kvs = Builder.load_string(KV)
        self.screen = Builder.load_string(KV)

    def on_start(self):
        self.root.ids.box.add_widget(
            MDExpansionPanel(
                icon="theme-light-dark",
                content=Content(),
                panel_cls=MDExpansionPanelOneLine(
                    text="Theme",
                )
            )
        )

    def theme_changer(self):
        self.theme_cls.theme_style = "Light"
        self.root.ids.mdt_color.md_bg_color = [1, 1, 1, 1]

    def theme_changer2(self):
        self.theme_cls.theme_style = "Dark"
        self.root.ids.mdt_color.md_bg_color = [0, 0, 0, 1]

    def build(self):
        self.theme_cls.theme_style = "Light"
        screen = Screen()
        screen.add_widget(self.kvs)
        return self.screen


ma = MainApp()
ma.run()

2nd code: I got from the kivymd documentation here https://github.com/kivymd/KivyMD/wiki/Components-Expansion-Panel

3rd code is much the same as the 2nd but I made my own:

from kivy.lang import Builder
from kivymd.app import MDApp
from kivymd.uix.boxlayout import MDBoxLayout
from kivymd.uix.expansionpanel import MDExpansionPanel, MDExpansionPanelOneLine

KV = '''
<Content>
    adaptive_height: True
    orientation: 'vertical'

    OneLineIconListItem:
        text: "Dark"
        divider: None
        IconLeftWidget:
            icon: 'weather-night'
            
    OneLineIconListItem:
        text: "Light"
        divider: None
        IconLeftWidget:
            icon: 'white-balance-sunny'


ScrollView:

    MDGridLayout:
        id: box
        cols: 1
        adaptive_height: True
'''


class Content(MDBoxLayout):
    """Custom content."""

    def __draw_shadow__(self, origin, end, context=None):
        pass


class Test(MDApp):
    def build(self):
        return Builder.load_string(KV)

    def on_start(self):
        self.root.ids.box.add_widget(
            MDExpansionPanel(
                icon="theme-light-dark",
                content=Content(),
                panel_cls=MDExpansionPanelOneLine(
                    text="Theme",
                )
            )
        )


Test().run()

My problem is, as seen in the example of problem video, that the expansion panel itself doesn't show up.

I am figuring this out as I go along, so among all the chaos I have tried, I have noticed that the position of the "Content" and all that's under it in relation the anchor layout of screen 'settings', causes the panel to show up but the content isn't inside.

Same effect with whether the "content" or "MDGridlayout" have the id: box.

In summary, I want to be able to create something like in the 2nd code but in the settings screen of my main app, or basically copy and paste the 3rd code into my main app.

Oh, and I may make this a question on it's own later, but if it's simple enough, how can I make it so when the theme is changed it becomes the default?

Took a while, but with help i finally got it. Here's an example with what i think are some key notes in the code #Comments#.

Hope this helps someone.

from kivymd.app import MDApp
from kivy.lang import Builder
from kivymd.uix.boxlayout import MDBoxLayout
from kivymd.uix.expansionpanel import MDExpansionPanel, MDExpansionPanelOneLine

KV = '''

#THE CONTENT GOES ABOVE EVERYTHING ELSE EVEN THE 1ST SCREEN.#
#IT IS REFERENCED LATER IN WHICH EVER SCREEN IT IS TO APPEAR USING MDGridLayout AND A def LATER ON#

#It should also always have these angle brackets <>#

<Content>
    size_hint_y: None
    height: self.minimum_height
    orientation: 'vertical'

    OneLineIconListItem:
        text: 'Dark theme'
        on_release:app.theme_changer2()
        divider: None
        IconLeftWidget:
            icon: 'weather-night'
            on_release:app.theme_changer2()

    OneLineIconListItem:
        text: 'Light theme'
        on_release:app.theme_changer()
        divider: None
        IconLeftWidget:
            icon: 'white-balance-sunny'
            on_release:app.theme_changer()

<Content2>
    size_hint_y: None
    height: self.minimum_height
    orientation: 'vertical'

    OneLineIconListItem:
        text: 'I try to explain what i think are key points to note'
        on_release:app.theme_changer2()
        divider: None
        IconLeftWidget:
            icon: 'weather-night'
            on_release:app.theme_changer2()

    OneLineIconListItem:
        text: 'Hope this helps someone else'
        on_release:app.theme_changer()
        divider: None
        IconLeftWidget:
            icon: 'white-balance-sunny'
            on_release:app.theme_changer()

MDScreen:

    MDNavigationLayout:

        ScreenManager:
            id: manager

            MDScreen:
                name: 'Home'

                #The location of this MDGridLayout shows it appears in the 1st screen.#

                MDGridLayout:
                    cols: 1
                    adaptive_height: True

                    #This id is used to reference what content goes to which expansion panel#

                    id: box2

                MDRaisedButton:
                    pos_hint: {"center_x": 0.5, "center_y": 0.5}
                    text: "PRESS ME"
                    on_release: manager.current = 'Home2'

            MDScreen:
                name: 'Home2'

                MDBoxLayout:
                    orientation: "vertical"

                    MDToolbar:
                        id: mdt_color
                        elevation: 10

                    ScrollView:
                        divider: 'None'

                        #The location of this MDGridLayout shows it appears in the 2nd screen.#

                        MDGridLayout:
                            cols: 1
                            adaptive_height: True
                            id: box

                MDIconButton:
                    pos_hint: {"center_x": 0.05, "center_y": 0.945}
                    icon: "keyboard-backspace"
                    on_release: manager.current = 'Home'

'''


# Every expansion panel should have a class corresponding to it's name e.g.#


class Content(MDBoxLayout):
    pass


# The class name is referenced in the contents= section below#


class Content2(MDBoxLayout):
    pass


class MainApp(MDApp):
    def theme_changer(self):
        self.theme_cls.theme_style = "Light"
        self.root.ids.mdt_color.md_bg_color = [1, 1, 1, 1]

    def theme_changer2(self):
        self.theme_cls.theme_style = "Dark"
        self.root.ids.mdt_color.md_bg_color = [0, 0, 0, 1]

    def build(self):
        return Builder.load_string(KV)

    def on_start(self):

        # Here you see the id box used#

        self.root.ids.box.add_widget(
            MDExpansionPanel(
                icon="theme-light-dark",

                # Here the content name Content is referenced in content=#

                content=Content(),
                panel_cls=MDExpansionPanelOneLine(
                    text="Theme",
                )
            )
        )

        # Here you see the id box2 used#

        self.root.ids.box2.add_widget(
            MDExpansionPanel(
                icon="theme-light-dark",

                # Here the content name Content2 is referenced in content=#

                content=Content2(),
                panel_cls=MDExpansionPanelOneLine(
                    text="Read the code #comments# for details",
                )
            )
        )


ma = MainApp()
ma.run()

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM