我如何在 KivyMD 中连接 类,python

how can I connect classes in KivyMD, python

我试着做一个应用程序作为一个问题,我不知道如何解决这个错误。

AttributeError: 'CustomItem' 对象没有属性 'delete_item'

我知道这是什么意思,CustomItem 是另一个 class,所以它没有那个 def,但是当我将该 def 复制到 CustomItem class 时,它没有对象面板。那么是否可以连接另一个 class ?

main.py

import kivy
kivy.require('1.11.1')

from helpers import screen_helper

from kivy.uix.screenmanager import Screen, ScreenManager
from kivymd.app import MDApp
from kivymd.uix.button import MDFillRoundFlatButton,MDFloatingActionButton, MDRectangleFlatButton, MDFloatingActionButtonSpeedDial, MDFlatButton, MDRoundFlatButton
from kivy.uix.image import Image
from kivy.lang import Builder
from kivy.uix.floatlayout import FloatLayout
from kivymd.uix.boxlayout import BoxLayout, MDBoxLayout
from kivymd.uix.toolbar import MDToolbar
from kivy.core.window import Window
from kivymd.uix.dialog import MDDialog
from kivymd.uix.taptargetview import MDTapTargetView
from kivymd.uix.menu import MDDropdownMenu, RightContent
from kivy.uix.dropdown import DropDown
from kivymd.uix.list import OneLineAvatarIconListItem
from kivymd.uix.label import MDLabel
from kivymd.uix.textfield import MDTextField
from kivymd.uix.snackbar import Snackbar
from kivymd.uix.card import MDSeparator
from kivymd.uix.list import MDList
from kivy.uix.scrollview import ScrollView
from kivymd.uix.floatlayout import MDFloatLayout
from kivy.properties import ObjectProperty
from kivy.core.window import Window
from kivymd.uix.gridlayout import GridLayout
from kivymd.uix.expansionpanel import MDExpansionPanel,MDExpansionPanelOneLine
from kivymd.uix.list import StringProperty,ThreeLineAvatarIconListItem
from kivy.properties import BooleanProperty
from kivymd.theming import ThemableBehavior
from kivymd.uix.bottomsheet import MDListBottomSheet
from kivy.factory import Factory
from kivymd.toast import toast
from kivy.animation import Animation

class ItemConfirm(OneLineAvatarIconListItem):
    divider = None

    def set_icon(self, choice):
        choice.active = True
        check_list = choice.get_widgets(choice.group)
        for check in check_list:
            if check != choice:
                check.active = False

class HomeScreen(Screen):
    choose_dialog= None
    choice = None
    help_dialog= None

    def show_ChooseDialog(self):
        if not self.choose_dialog:
            self.choose_dialog = MDDialog(title="Test zameraný pre:", type="confirmation",
                    size_hint=[0.9, 0.5], auto_dismiss=False,
                    items=[ItemConfirm(text="osobné zlepšenie",on_release= self.next_page_me,
                                       on_press= self.close_choose_dialog,),
                            ItemConfirm(text="prácu v tíme", on_release= self.next_page_team,
                                        on_press= self.close_choose_dialog, ),
                            ItemConfirm(text="osobné vzťahy",on_release= self.next_page_we,
                                        on_press= self.close_choose_dialog,)],)
            self.choose_dialog.open()


    def close_choose_dialog(self, obj):
        self.choose_dialog.dismiss()
        print(self.choose_dialog.items)

    def next_page_me (self,obj):
        self.manager.current = "motivationme"
    def next_page_team (self,obj):
        self.manager.current = "motivationteam"
    def next_page_we (self,obj):
        self.manager.current = "motivationwe"

    def show_HelpDialog(self):
        ok_button = MDRectangleFlatButton (text= "Rozummiem",on_release=self.close_help_dialog)
        self.help_dialog = MDDialog(title="O čo v teste ide?", text="obkec",
                              size_hint=[0.8, 0.5], auto_dismiss=False,
                              buttons=[ok_button])
        self.help_dialog.open()

    def close_help_dialog(self,obj):
        self.help_dialog.dismiss()

    def main_navigate(self, button):
        if button.icon == "home":
            self.manager.current = "home"
        elif button.icon == "lightning-bolt":
            self.manager.current = "goals"
        elif button.icon == "notebook":
            self.manager.current = "history"

class MotivationScreenMe(Screen):

    def main_navigate(self, button):
        if button.icon == "home":
            self.manager.current = "home"
        elif button.icon == "lightning-bolt":
            self.manager.current = "goals"
        elif button.icon == "notebook":
            self.manager.current = "history"

    def test_name(self):
        subor = open("package.txt", "w")
        subor.write(self.ids.nazov_testu.text)


class MotivationScreenTeam(Screen):
    nazov = ObjectProperty(None)
    nazov_testu = ObjectProperty(None)
    created= ObjectProperty(None)

    def main_navigate(self, button):
        if button.icon == "home":
            self.manager.current = "home"
        elif button.icon == "lightning-bolt":
            self.manager.current = "goals"
        elif button.icon == "notebook":
            self.manager.current = "history"

    def test_name(self):
        subor = open("package.txt", "w")
        subor.write(self.ids.nazov_testu.text)

class MotivationScreenWe(Screen):
    nazov = ObjectProperty(None)
    nazov_testu = ObjectProperty(None)

    def main_navigate(self, button):
        if button.icon == "home":
            self.manager.current = "home"
        elif button.icon == "lightning-bolt":
            self.manager.current = "goals"
        elif button.icon == "notebook":
            self.manager.current = "history"

    def test_name(self):
        subor = open("package.txt", "w")
        subor.write(self.ids.nazov_testu.text)

class TestConfirm(OneLineAvatarIconListItem):
    divider = None

    def set_icon(self, choice):
        choice.active = True
        check_list = choice.get_widgets(choice.group)
        for check in check_list:
            if check != choice:
                check.active = False

class TestScreenV(Screen):

    snackbar = None
    p = 0
    r = 0
    def show_example_snackbar(self):
        if not self.snackbar:
            self.snackbar = Snackbar(text="Pokračovať na druhý test?",
                                        snackbar_x="10dp",
                                        snackbar_y="10dp",
                                     bg_color= (0.96,0.79,0.09, 1),)
            self.snackbar.size_hint_x = ( Window.width -
                                          (self.snackbar.snackbar_x * 2)) / Window.width
            self.snackbar.buttons = [MDFlatButton(text="Áno",text_color=(1, 1, 1, 1),
                                                  on_release=self.evaluate,
                                                  on_press= self.snackbar.dismiss),]
            self.snackbar.open()

    def evaluate (self,obj):
        self.manager.current= "testm"
        self.manager.transition.direction = 'left'

    def plus(self):
        self.p = self.p +4.16
        self.ids.progress.value = self.p

class TestScreenM(Screen):
    snackbar = None
    p = 0
    r = 0
    def show_example_snackbar(self):
        if not self.snackbar:
            self.snackbar = Snackbar(text="Naozaj ukončiť ?",
                                        snackbar_x="10dp",
                                        snackbar_y="10dp",
                                     bg_color= (0.96,0.79,0.09, 1),)
            self.snackbar.size_hint_x = ( Window.width -
                                          (self.snackbar.snackbar_x * 2)) / Window.width
            self.snackbar.buttons = [MDFlatButton(text="Uložiť",text_color=(1, 1, 1, 1),
                                                  on_release=self.evaluate,
                                                  on_press= self.snackbar.dismiss),]
            self.snackbar.open()

    def evaluate (self,obj):
        self.manager.current= "history"
        self.manager.transition.direction = 'left'

    def plus(self):
        self.p = self.p +4.16
        self.ids.progress.value = self.p

class MeContent(MDBoxLayout):
    pass
class TeamContent(MDBoxLayout):
    pass
class WeContent(MDBoxLayout):
    pass

class GoalsScreen(Screen):
    panel_is_open = False

    def on_enter(self):
        self.panel0 = MDExpansionPanel(icon="flash",content=WeContent(),
                                       panel_cls=MDExpansionPanelOneLine(text="Definuj si ciele"), )

        self.ids.cards.add_widget(self.panel0)
        self.panel0.bind(on_open=self.panel_open, on_close=self.panel_close)

        self.panel1 = MDExpansionPanel(icon="human-greeting",content=MeContent(),
                panel_cls=MDExpansionPanelOneLine(text="Ja"),)

        self.ids.cards.add_widget(self.panel1)
        self.panel1.bind(on_open=self.panel_open, on_close=self.panel_close)

        self.panel2 = MDExpansionPanel(icon="human-capacity-increase", content=TeamContent(),
                                       panel_cls=MDExpansionPanelOneLine(text="Tím"), )

        self.ids.cards.add_widget(self.panel2)
        self.panel2.bind(on_open=self.panel_open, on_close=self.panel_close)

        self.panel3 = MDExpansionPanel(icon="human-male-female", content=WeContent(),
                                       panel_cls=MDExpansionPanelOneLine(text="Vzťah"), )

        self.ids.cards.add_widget(self.panel3)
        self.panel3.bind(on_open=self.panel_open, on_close=self.panel_close)

    def panel_open(self, *args):
        self.panel_is_open = True

    def panel_close(self, *args):
        self.panel_is_open = False

    def main_navigate(self, button):
        if button.icon == "home":
            self.manager.current = "home"
        elif button.icon == "lightning-bolt":
            self.manager.current = "goals"
        elif button.icon == "notebook":
            self.manager.current = "history"

class Content(MDBoxLayout):
    pass

class CustomItem(ThreeLineAvatarIconListItem):

    def sh_delete_item(self):
        yes_button = MDFillRoundFlatButton (text="Zmazať", on_release=self.close_del_dialog
                                            ,on_press= self.delete_item)
        no_button = MDRoundFlatButton (text= "Zrušiť", on_release= self.close_del_dialog)
        self.del_dialog = MDDialog(title="Naozaj zmazať test?",
                                    size_hint=[0.8, 0.5], auto_dismiss=False,
                                    buttons=[ no_button,yes_button])
        self.del_dialog.open()

    def close_del_dialog(self, obj):
        self.del_dialog.dismiss()

    def delete_item(self, item):
        self.parent.get_screen('history')
        self.panel.content.remove_widget(item)
        self.panel.height -= item.height
        for index, val in enumerate(self.panel.content.children[::-1]):
            val.secondary_text = str(index + 1)

    icon = StringProperty('')

class HistoryScreen(Screen):
    panel_is_open = False
    def on_enter(self):
        self.ids.panel_container.clear_widgets()  # to avoid re-adding panel each time


        self.panel= MDExpansionPanel(icon="all.png", panel_cls=MDExpansionPanelOneLine(
                        text="Moje testy",),
                    content=Content())

        self.ids.panel_container.add_widget(self.panel)
        self.panel.bind(on_open=self.panel_open, on_close=self.panel_close)

    def panel_open(self, *args):
        self.panel_is_open = True

    def panel_close(self, *args):
        self.panel_is_open = False

    def delete_item(self, item):
        self.panel.content.remove_widget(item)
        self.panel.height -= item.height
        for index, val in enumerate(self.panel.content.children[::-1]):
            val.secondary_text = str(index + 1)

    def add_into_panel(self, Názov, interval):
        item = CustomItem(text=f"{len(self.panel.content.children) + 1} Názov",
                          secondary_text="ukazovatel",tertiary_text="datoum" ,icon="book-outline")
        self.panel.content.add_widget(item)
        if self.panel_is_open and len(self.panel.content.children) > 1:
            self.panel.height += item.height
        elif self.panel_is_open and len(self.panel.content.children) == 1:
            self.panel.height -= (self.panel.height - item.height) - self.panel.panel_cls.height

    def callback_for_menu_items(self, *args):
        toast(args[0])

    def show_bottom_sheet(self,):
        bottom_sheet_menu = MDListBottomSheet(
            bg_color=[1, 1, 1, 1],
            radius_from="top",)

        for i in range(1, 22):
            bottom_sheet_menu.add_item(

                f"d {i}",
                lambda x, y=i: self.callback_for_menu_items(
                    f"d {y}"
                ),
            )
        bottom_sheet_menu.open()

    def main_navigate(self, button):
        if button.icon == "home":
            self.manager.current = "home"
        elif button.icon == "lightning-bolt":
            self.manager.current = "goals"
        elif button.icon == "notebook":
            self.manager.current = "history"

class MainApp(MDApp):

    def build(self):
        self.theme_cls.primary_palette = "Red"
        self.theme_cls.primary_hue = "500"
        self.theme_cls.theme_style = "Light"

        #db= DataBase("package.txt")

        screen = Builder.load_string(screen_helper)
        return screen

MainApp().run()


.kv

screen_helper = """
ScreenManager:
    HomeScreen:
    MotivationScreenMe:
    MotivationScreenTeam:
    MotivationScreenWe:
    TestScreenV:
    TestScreenM:
    GoalsScreen:
    HistoryScreen:

<HomeScreen>:
    name: "home"

    MDLabel:
        text: "Spoznaj seba"
        font_size: (root.width**2 + root.height**2) / 13**4
        halign: "center"
        pos_hint: { "center_x" :0.7, "center_y":0.9}
        theme_text_color: "Custom"
        text_color: 0.96,0.79,0.09, 1
    Image:
        source: "all.png"
        pos_hint: { "center_x" :0.5, "center_y":0.5}
        size_hint: (1,1)

    MDFloatingActionButton:
        icon: "play-circle-outline"
        size_hint: None, None
        pos_hint: {"center_x" :0.5, "center_y":0.08}
        md_bg_color: app.theme_cls.primary_color
        on_release: root.show_ChooseDialog()

    MDFloatingActionButton:
        icon: "help-circle-outline"
        md_bg_color: app.theme_cls.primary_color
        pos_hint: { "center_x" :0.15, "center_y":0.08}
        on_release: root.show_HelpDialog()

    MDFloatingActionButtonSpeedDial:
        callback: root.main_navigate
        data: 
            {'home': 'Domov',
            'lightning-bolt': 'Ciele',
            'notebook': 'Moje testy'}

<ItemConfirm>
    on_release: root.set_icon(check)

    CheckboxLeftWidget:
        id: check
        group: "check"            

<MotivationScreenMe>:
    name: "motivationme"
    nazov_testu: nazov_testu

    MDCard:
        orientation: "vertical"
        pos_hint:{ "center_x" :0.5, "center_y": 0.6} 
        size_hint: 0.8, 0.7
        padding: "8dp"

        MDLabel:
            text: "Osobné zlepšenie"
            font_size: (root.width**2 + root.height**2) / 13**4
            halign: "center"
            pos_hint: { "center_x" :0.3, "center_y":0.95}
            size_hint: 0.8, 0.1
            theme_text_color: "Custom"
            text_color: app.theme_cls.primary_color

        MDSeparator:
            height: "1dp"

        MDLabel:
            text: "bla bla bla bla bla "
            font_size: (root.width**2 + root.height**2) / 13**4
            halign: "center"

    MDTextField:
        id: nazov_testu
        hint_text:"Zadaj názov testu"
        helper_text: "napr. Test 1"
        helper_text_mode: "on_focus"
        pos_hint: { "center_x" :0.5, "center_y":0.2}
        size_hint: 0.8,0.1 

    MDFloatingActionButton:
        icon: "play-circle-outline"
        pos_hint: { "center_x" :0.5, "center_y":0.08}
        md_bg_color: app.theme_cls.primary_color
        on_release: 
            root.manager.current = "testv"
            root.manager.transition.direction = 'up'
        on_press: root.test_name()

    MDFloatingActionButtonSpeedDial:
        callback: root.main_navigate
        data: 
            {'home': 'Domov',
            'lightning-bolt': 'Ciele',
            'notebook': 'Moje testy'} 

<MotivationScreenTeam>:
    name: "motivationteam"
    nazov_testu: nazov_testu

    MDCard:
        orientation: "vertical"
        pos_hint:{ "center_x" :0.5, "center_y": 0.6} 
        size_hint: 0.8, 0.7
        padding: "8dp"

        MDLabel:
            text: "Práca v tíme"
            halign: "center"
            pos_hint: { "center_x" :0.3, "center_y":0.95}
            font_size: (root.width**2 + root.height**2) / 13**4
            size_hint: 0.8, 0.1
            theme_text_color: "Custom"
            text_color: app.theme_cls.primary_color

        MDSeparator:
            height: "1dp"

        MDLabel:
            text: "bla bla bla bla bla "
            font_size: (root.width**2 + root.height**2) / 13**4
            halign: "center"

    MDTextField:
        id: nazov_testu
        hint_text:"Zadaj názov testu"
        helper_text: "napr. Test 1"
        helper_text_mode: "on_focus"
        pos_hint: { "center_x" :0.5, "center_y":0.2}
        size_hint: 0.8,0.1 

    MDFloatingActionButton:
        icon: "play-circle-outline"
        pos_hint: { "center_x" :0.5, "center_y":0.08}
        md_bg_color: app.theme_cls.primary_color
        on_release: 
            root.manager.current = "testv"
            root.manager.transition.direction = 'up'
        on_press: root.test_name()

    MDFloatingActionButtonSpeedDial:
        callback: root.main_navigate
        data: 
            {'home': 'Domov',
            'lightning-bolt': 'Ciele',
            'notebook': 'Moje testy'} 

<MotivationScreenWe>:
    name: "motivationwe"
    nazov_testu: nazov_testu

    MDCard:
        orientation: "vertical"
        pos_hint:{ "center_x" :0.5, "center_y": 0.6} 
        size_hint: 0.8, 0.7
        padding: "8dp"

        MDLabel:
            text: "Pre vzťah"
            halign: "center"
            pos_hint: { "center_x" :0.3, "center_y":0.95}
            font_size: (root.width**2 + root.height**2) / 13**4
            size_hint: 0.8, 0.1
            theme_text_color: "Custom"
            text_color: app.theme_cls.primary_color

        MDSeparator:
            height: "1dp"

        MDLabel:
            text: "bla bla bla bla bla "
            font_size: (root.width**2 + root.height**2) / 13**4
            halign: "center"

    MDTextField:
        id: nazov_testu
        hint_text:"Zadaj názov testu"
        helper_text: "napr. Test 1"
        helper_text_mode: "on_focus"
        pos_hint: { "center_x" :0.5, "center_y":0.2}
        size_hint: 0.8,0.1 

    MDFloatingActionButton:
        icon: "play-circle-outline"
        pos_hint: { "center_x" :0.5, "center_y":0.08}
        md_bg_color: app.theme_cls.primary_color
        on_release: 
            root.manager.current = "testv"
            root.manager.transition.direction = 'up'
        on_press: root.test_name()

    MDFloatingActionButtonSpeedDial:
        callback: root.main_navigate
        data: 
            {'home': 'Domov',
            'lightning-bolt': 'Ciele',
            'notebook': 'Moje testy'} 

<TestConfirm>
    on_release: root.set_icon(check)

    CheckboxLeftWidget:
        id: check 

<TestScreenV>:
    name: "testv"
    MDCard:
        orientation: "vertical"
        padding: "8dp"
        size_hint: 0.9,0.7
        pos_hint: {"center_x": .5, "center_y": .6}

        OneLineListItem:                          
            text: "Vyber možnosť, ktorá ťa NAJVIAC vystihuje"
            theme_text_color: "Custom"
            text_color: app.theme_cls.primary_color
            font_size: (root.width**2 + root.height**2) / 13**4

        ScrollView:
            do_scroll_x: False
            BoxLayout:
                orientation: 'vertical'
                size_hint_y: None
                height: dp(6530)

                OneLineListItem:
                    text: "1/24 "
                    theme_text_color: "Custom"
                    text_color: app.theme_cls.primary_color
    MDFloatingActionButton:
        icon: "check-circle-outline"
        pos_hint: { "center_x" :0.5, "center_y":0.08}
        md_bg_color: app.theme_cls.primary_color
        on_release: root.show_example_snackbar()


    MDProgressBar:
        id: progress
        size_hint_x: 0.8
        size_hint_y: 0.08
        color: app.theme_cls.accent_color
        pos_hint: { "center_x" :0.5, "center_y":0.2}

<TestScreenM>:
    name: "testm"

    MDCard:
        orientation: "vertical"
        padding: "8dp"
        size_hint: 0.9,0.7
        pos_hint: {"center_x": .5, "center_y": .6}

        OneLineListItem:                          
            text: "Vyber možnosť, ktorá ťa NAJMENEJ vystihuje"
            theme_text_color: "Custom"
            text_color: 0.19,0.38,0.17,1
            font_size: (root.width**2 + root.height**2) / 13**4

        ScrollView:
            do_scroll_x: False
            BoxLayout:
                orientation: 'vertical'
                size_hint_y: None
                height: dp(6530)

                OneLineListItem:
                    text: "1/24 "
                    theme_text_color: "Custom"
                    text_color: 0.19,0.38,0.17,1
                    
                TestConfirm:
                    text: "prieberčivý"
                    font_size: (root.width**2 + root.height**2) / 13**4
                    text_of_the_option: "s"
                    on_press: root.plus()
     MDFloatingActionButton:
        icon: "check-circle-outline"
        pos_hint: { "center_x" :0.5, "center_y":0.08}
        md_bg_color: app.theme_cls.primary_color
        on_release: root.show_example_snackbar()

    MDProgressBar:
        id: progress
        size_hint_x: 0.8
        size_hint_y: 0.08
        color: app.theme_cls.accent_color
        pos_hint: { "center_x" :0.5, "center_y":0.2}

<MeContent>:
    adaptive_height: True
    orientation: 'vertical'
    
    spacing: "12dp"
    size_hint_y: None
    height: "120dp"
    
    
    
    MDLabel:
        text: "Ako by si ..?"
        theme_text_color: "Custom"
        text_color: 0.96,0.79,0.09, 1
    
    MDTextField:
        hint_text: "Ciel No.1"
        mode: "rectangle"
    MDTextField:
        hint_text: "Ciel No.2"
        mode: "rectangle"
    MDTextField:
        hint_text: "Ciel No.3"
        mode: "rectangle"
        
<GoalsScreen>:
    name: "goals"
    
    ScrollView:
        MDList:
            id: cards
        
    MDRoundFlatIconButton:
        text: "technika SMART" 
        icon: 'lightbulb-on-outline'
        theme_text_color: "Custom"
        text_color: app.theme_cls.accent_color
        pos_hint: {"center_y": .2}
              
               
    MDFloatingActionButtonSpeedDial:
        callback: root.main_navigate
        data: 
            {'home': 'Domov',
            'lightning-bolt': 'Ciele',
            'notebook': 'Moje testy'}
    
<Content>
    adaptive_height: True
    orientation: 'vertical'
    
<CustomItem>:
    IconLeftWidget:
        icon: root.icon

    IconRightWidget:
        icon: 'delete'
        on_press: root.sh_delete_item()
        
#:import Clock kivy.clock.Clock
#:import partial functools.partial
            
<HistoryScreen>:
    name: "history"
    
    ScrollView:
        MDList:
            id: panel_container
                      
    MDFillRoundFlatButton: 
        text:"Pridaj test"
        pos_hint:{ "center_x" :0.5, "center_y": 0.5} 
        size_hint: None, None
        on_release:Clock.schedule_once(partial(root.add_into_panel, 'text'), .5) 
                    
    MDFillRoundFlatButton:
        pos_hint:{ "center_x" :0.5, "center_y": 0.1} 
        size_hint: None, None
        text: "Typy osobností"
        on_press: root.show_bottom_sheet()
        
    MDFloatingActionButtonSpeedDial:
        callback: root.main_navigate
        data: 
            {'home': 'Domov',
            'lightning-bolt': 'Ciele',
            'notebook': 'Moje testy'}

       
"""                   
    
    ```    

如果你想访问 HistoryScreen 那么你必须像 self.parent.get_screen('history') 那样做然后你可以从 HistoryScreen

访问其他小部件或任何你想要的东西