3

I need to create a list of items with a custom row layout. Every row should have an image, one main button and two other small buttons (side by side), after pressing the main button I would like to display a short text in a scroll view under the row. I am using a custom BoxLayout that looks like this:

<InfoRow@BoxLayout>:
landmarkName: self.landmarkName
pozaId: self.pozaId
rowId: self.rowId
starId: self.starId
svId: self.svId

show_infoId: self.show_infoId
orientation: 'vertical'
size_hint_y: None
height:self.minimum_height

BoxLayout:
    size_hint_y: None
    height: 50
    pos_hint: {"x": 0, 'top': 1}

    AsyncImage: 
        size_hint_x: 0.2
        id: root.pozaId
        source: root.srcImg

    ToggleButton:
        id: root.rowId
        font_size: self.height * 0.5
        text_size: self.size 
        text: root.landmarkName
        on_release: root.toggle_info()

    ToggleButton:
        #on_release: self.parent.parent.ids.calc_input.text += self.text
        size_hint: None, None
        width: 50
        height: 50
        background_down: 'data/check.png'
        background_normal: 'data/full_plus.png'

    ToggleButton:
        id: root.starId
        size_hint: None, None
        height: 50
        width: 50
        background_down: root.starImg
        background_normal: root.starImg
        on_release: root.saveLocation() 

ScrollView:
    id: root.svId
    size_hint_y: None
    pos_hint: {"x": 0.12, 'top': 1}
    height: 0

    InfoTextInput:
        id: root.show_infoId
        text: ""
        size_hint_y: None
        height: self.minimum_height

And my python code:

class InfoRow(BoxLayout):
pozaId = StringProperty(' ')
rowId = StringProperty(' ')
starId = StringProperty(' ')
svId= StringProperty(' ')
show_infoId=StringProperty(' ')
landmarkName = StringProperty(' ')
pressed = False
starImg = StringProperty('data/white.png')
srcImg = StringProperty('data/white.png')

def __init__(self, **kwargs):
    super(InfoRow, self).__init__(**kwargs)

def toggle_info(self):

    self.pressed = not self.pressed
    if self.pressed:
        height = self.height * .25
    else:
        height = 0

    Animation(height=height, d=.25, t='out_quart').start(
            self.ids[self.svId])

    if not self.pressed:
        self.ids[self.show_infoId].focus = False
        return

    self.ids[self.show_infoId].text = "TO DO"
    self.ids[self.svId].scroll_y = 1

def saveLocation(self):
    pass

Where I create my list:

class MainScreen(Screen):

def getSpecificInfo(self, category):

    ...

    self.ids["extraInfo"].clear_widgets()
    for i in range (0, 15):
        wid = InfoRow(pozaId = pozaId, landmarkName=landmarkName, starImg = starImg ,rowId = rowId, starId = starId, svId= svId, show_infoId=show_infoId)
        self.ids["extraInfo"].add_widget(wid)

For now I managed to create dynamically my list, but after pressing the button the ScrollView doesn't show and I have the following error:

self.ids[self.svId]) KeyError: 'sv0'

I have no idea what I am doing wrong. Any ideas?

AlinaC
  • 31
  • 1

1 Answers1

0

Problem - KeyError

self.ids[self.svId])
 KeyError: 'sv0'

Root Cause

It means that the value, 'sv0' in self.svId does not exist in self.ids dictionary type property.

Note

Widget created dynamically in Python code, the id assigned to the widget is not added to self.ids. You might want to create your own dictionary to store them for accessing it later.

ikolim
  • 15,721
  • 2
  • 19
  • 29
  • Can you tell me what information should I store in the dictionary and how to access the ScrollView from it? I suppose I should store the id and the widget before adding it to my layout, but I'm not sure how I can access the ScrollView, or maybe I can insert the row layout and the scrollview separately? – AlinaC Jun 05 '19 at 22:42