Reputation: 1183
I want to save a variable (label.text) in kivy for an android app and when the App restarts it should load the variable back into label.text.
I tried to use JsonStore to save the variable https://kivy.org/docs/api-kivy.storage.html#
Is there a better way to save variables ?
But when I run the code I get the following error:
ValueError: No JSON object could be decoded
here is my main.py file:
from kivy.app import App
from kivy.storage.jsonstore import JsonStore
from kivy.uix.boxlayout import BoxLayout
from kivy.core.window import Window
class Test(BoxLayout):
Window.clearcolor = (1, 1, 1, 1)
def save(self):
store = JsonStore('hello.json')
store.put('tito', score=label.text)
class MyApp(App):
def build(self):
return Test()
def on_start(self):
store = JsonStore('hello.json')
label.text = store.get('tito')['score']
if __name__ == '__main__':
MyApp().run()
here is my my.kv file:
<Test>:
orientation: "vertical"
BoxLayout:
Label:
id: label
text: '0'
color: 0,0,0,1
pos: 250,200
size: 50,50
font_size:30
Button:
text: 'save'
on_release: root.save()
Button:
text: 'load'
on_release:
Button:
size_hint: 1, .5
text: 'click me'
on_press: label.text = str(int(label.text)+1)
here is the full error message:
Traceback (most recent call last):
File "main.py", line 25, in <module>
MyApp().run()
File "/usr/lib/python2.7/dist-packages/kivy/app.py", line 823, in run
self.dispatch('on_start')
File "kivy/_event.pyx", line 699, in kivy._event.EventDispatcher.dispatch (kivy/_event.c:7394)
File "main.py", line 20, in on_start
store = JsonStore('hello.json')
File "/usr/lib/python2.7/dist-packages/kivy/storage/jsonstore.py", line 25, in __init__
super(JsonStore, self).__init__(**kwargs)
File "/usr/lib/python2.7/dist-packages/kivy/storage/__init__.py", line 133, in __init__
self.store_load()
File "/usr/lib/python2.7/dist-packages/kivy/storage/jsonstore.py", line 34, in store_load
self._data = loads(data)
File "/usr/lib/python2.7/json/__init__.py", line 339, in loads
return _default_decoder.decode(s)
File "/usr/lib/python2.7/json/decoder.py", line 364, in decode
obj, end = self.raw_decode(s, idx=_w(s, 0).end())
File "/usr/lib/python2.7/json/decoder.py", line 382, in raw_decode
raise ValueError("No JSON object could be decoded")
ValueError: No JSON object could be decoded
Thanks in advance
Upvotes: 1
Views: 1465
Reputation: 4513
The error is a bit generic but it seems that you have invalid JSON. Your JSON should be similar to:
{"tito": {"score": "3"}}
You can use __init__
method in your Test
class to load the Json at start, i thing that it is most simple than use on_start
method in this case.
On the other hand, you need test if JSON file and key exist before try to get it. Otherwise, you can recibe a KeyError
exception. You can use try-except for this.
from kivy.app import App
from kivy.storage.jsonstore import JsonStore
from kivy.uix.boxlayout import BoxLayout
from kivy.core.window import Window
from kivy.lang import Builder
from kivy.properties import ObjectProperty
kv_text = '''\
<Test>:
orientation: "vertical"
label: label
BoxLayout:
Label:
id: label
text: '0'
color: 0,0,0,1
pos: 250,200
size: 50,50
font_size:30
Button:
text: 'save'
on_release: root.save()
Button:
text: 'load'
on_release: root.load()
Button:
size_hint: 1, .5
text: 'click me'
on_press: label.text = str(int(label.text)+1)
'''
class Test(BoxLayout):
label = ObjectProperty()
Window.clearcolor = (1, 1, 1, 1)
def __init__(self, **kwargs):
super(Test, self).__init__(**kwargs)
self.store = JsonStore('hello.json')
self.load()
def save(self):
self.store.put('tito', score= self.label.text)
def load(self):
try:
self.label.text = self.store.get('tito')['score']
except KeyError:
pass
class MyApp(App):
def build(self):
Builder.load_string(kv_text)
return Test()
if __name__ == '__main__':
MyApp().run()
Upvotes: 2