Search code examples
pythonjsonkivypython-3.6jsonstore

How can I use individual json storage keys for use as the text on a button with kivy?


I am trying to take text input, save it to a jsonstore, then use each individual key in the jsonstore as the text on a button. I've read all the relevant documentation that I can think of, I've tried searching google, and I've tried searching on here. I've tried indexing the keys, but that isn't supported. I really just can't figure it out. It's the last main feature that I need to have everything running.

Here is my python script for the part I am talking about.

class ScreenSix(Screen):

def Create_ShopList(self):
    store = JsonStore('user_meals.json')
    ingredients = store.get(self._name.text)['ingredients']
    return ingredients

def Meal_Options(self):
    store = JsonStore('users_meals.json')
    meals = store.keys()
    return meals

Here is the relevant part of my kv file.

<ScreenSix>:
name: 'shoplist'
id: shoplist

FloatLayout:
    canvas:
        Rectangle:
            pos: self.pos
            size: self.size
            source: '20.png'

    Label:
        text: 'Create Shopping List'
        font_size: 60
        pos_hint: {'center_x':.5,'center_y':.8}
        color: 0,0,0,1

    Label:
        text: 'Which meals would you like to add?'
        font_size: 40
        pos_hint: {'center_x':.5,'center_y':.7}
        color: 0,0,0,1

    Button:
        text: 'Menu'
        font_size: 36
        size_hint: .2,.1
        pos_hint: {'left':1,'y':0}
        on_release: app.root.current='menu'

    Button:
        text: 'Quit'
        font_size: 36
        size_hint: .2,.1
        pos_hint: {'right':1,'y':0}
        on_release: app.root.current='open'

    Button:
        text: ''
        font_size: 36
        size_hint: .2,.1
        pos_hint: {'center_x':.18,'center_y':.6}
        on_release: root.Create_ShopList()

    Button:
        text: ''
        font_size: 36
        size_hint: .2,.1
        pos_hint: {'center_x':.39,'center_y':.6}

    Button:
        text: ''
        font_size: 36
        size_hint: .2,.1
        pos_hint: {'center_x':.6,'center_y':.6}

    Button:
        text: ''
        font_size: 36
        size_hint: .2,.1
        pos_hint: {'center_x':.81,'center_y':.6}

I want to get the buttons text to be the names which are saved as the keys in my json storage. The last few buttons are the buttons I want the meal names to be on, and I'm using the first one as a test button while I try to figure it out. I'm worried that I might not be able to do it, and if that's the case I don't know what a good alternative would be.


Solution

  • You could use RecycleView for this.
    I made a little exapmle of this.
    Try this:

    from kivy.app import App
    from kivy.lang import Builder
    from kivy.uix.button import Button
    from kivy.uix.recycleview import RecycleView
    
    from kivy.storage.jsonstore import JsonStore
    
    
    store = JsonStore("buttons.json")
    
    store.put('button1', font_size="40sp", color=(1,.5,.5, 1))
    store.put('button2', font_size="20sp", color=(.5,1, 1, 1))
    store.put('button3', font_size="30sp", color=(1,.5,.5, 1))
    store.put('button4', font_size="10sp", color=(.5,1, 1, 1))
    
    for i in store: store[i]["text"] = i    
    
    items = [store[i] for i in store]
    
    
    class MyButton(Button):
    
        def print_data(self,data):
            print(data)
    
    
    class MyRecycleView(RecycleView):
    
        def __init__(self, **kwargs):
            super(MyRecycleView,self).__init__(**kwargs)
            self.data = items
            self.refresh_from_data()
    
    
    KV = '''
    
    <MyButton>:
        on_release:
            root.print_data(self.text)
    
    BoxLayout:
        orientation: 'vertical'
        MyRecycleView:
            id: rv
            viewclass: 'MyButton'
            RecycleBoxLayout:
                orientation: 'vertical'
                default_size: None, dp(56)
                default_size_hint: 1, None
                size_hint_y: None
                height: self.minimum_height
    
    '''
    
    
    class Test(App):
        def build(self):
            root = Builder.load_string(KV)
            return root
    
    
    Test().run()