0

I try to make an app as a questionary, I dont know how to figure this error out.

AttributeError: 'CustomItem' object has no attribute 'delete_item'

I know what does it mean, that CustomItem is another class so it hasnt that def, but when i copied that def into CustomItem class, it hasnt object panel. So is it possible to connect another 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'}

       
"""                   
    
    ```    

1 Answers1

0

If you want to access HistoryScreen then you have to do it like self.parent.get_screen('history') then you can access other widgets or anything else you want from HistoryScreen

Ankit Sangwan
  • 1,138
  • 1
  • 7
  • 20
  • Could you give me an example, where i may to write it please? Because I dont know what you think – Rebeka Panáková Jan 07 '21 at 07:33
  • Sure, but can you include full code including your imports of .py file. It will really help me. Then I will make changes in that code and write back to you – Ankit Sangwan Jan 07 '21 at 09:48
  • Ok, I checked it. It didn't know the language you have written so I was a had to depend only on code. So in your code what you have done is defined another class called `CustomItem`. In your kivy code the `CustomItem` class doesn't have a parent class i.e its independent so you can't use `self.parent` or any other way to access other class in kivy code. So you can't do anything with help of kivy. Now coming over to python part. The class `CustomItem` is used in `HistoryScreen`. In `CutomItem` class you can use `HistoryScreen.delete_item()` to call the function `delete_item` of `HistoryScreen`. – Ankit Sangwan Jan 08 '21 at 14:42
  • But the problem is that the `panel` defined in `HistoryScreen` couldn't be accessed by that which will cause an error. So with current approach, I don't think you can do that. What you can do right now is use kivy code, give `ids` to different classes in kivy and access those classes using that to change the values and all that or try to make your code in the same class – Ankit Sangwan Jan 08 '21 at 14:45