Использование jsonstore в Киви - PullRequest
0 голосов
/ 10 января 2019

Я создал графический интерфейс на основе этого вопроса , пытаясь научить себя, как использовать jsonstore. У меня нет очков репутации, чтобы добавить комментарий, поэтому я задаю свой вопрос здесь. Я думаю, что у меня есть основная идея, но по какой-то причине я не могу сохранить данные в файл JSON. Я получаю следующую ошибку:

AttributeError: 'NoneType' object has no attribute 'text'

Я пытался следовать документации, но нигде не вижу, где бы она объяснила, что я делаю неправильно.

main.py

from kivy.storage.jsonstore import JsonStore
from kivy.app import App
from kivy.lang import Builder
from kivy.uix.screenmanager import Screen, ScreenManager
from kivy.core.window import Window
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.widget import Widget
from kivy.properties import BooleanProperty, ListProperty, StringProperty, ObjectProperty


Window.clearcolor = (0.02745098, 0.074509804, 0.121568627, 1)
Window.size = (2000, 900)

class TitleScreen(Screen):
    pass

class MainScreen(Screen):
    pass

class CreateProfile(Screen):
    First = ObjectProperty()
    Middle = ObjectProperty()
    Last = ObjectProperty()

    def __init__(self, **kwargs):
        super(CreateProfile, self).__init__(**kwargs)
        self.store = JsonStore("bco.json")
        self.load()

    def save(self):
        self.store.put('profile', first = self.label.text)
        self.store.put('profile', middle = self.label.text)
        self.store.put('profile', last = self.label.text)

    def load(self):
        try:
            self.Last.text = self.store.get('profile')['score']
        except KeyError:
            pass


class CreatePacket(Screen):
    pass

class ScreenManagement(ScreenManager):
    pass

presentation = Builder.load_file("customwidget.kv")

class CustomWidgetApp(App):
    def build(self):
        return presentation

if __name__ == "__main__":
    CustomWidgetApp().run()
**

1013 customwidget.kv

#: import FadeTransition kivy.uix.screenmanager.FadeTransition
#: import hex kivy.utils.get_color_from_hex
#: import FocusBehaviors kivy.uix.behaviors.focus

ScreenManagement:
    transition: FadeTransition()
    TitleScreen:
    MainScreen:
    CreateProfile:
    CreatePacket:

<MainLabel@Label>:
    font_size:50
    bold: True
    size_hint_x: 1
    size_hint_y: 1.85
    color: 0.396078431, 0.803921569, 0.807843137, 1
    font_name: '/home/jarren/PycharmProjects/BCO_Form_Filler/practice/pirulen rg.ttf'

<SubLabel@Label>:
    font_size: 35
    bold: True
    halign: "center"
    size_hint_x: 1
    size_hint_y: 1.5
    color: 0.396078431, 0.803921569, 0.807843137, 1
    font_name: '/home/jarren/PycharmProjects/BCO_Form_Filler/practice/pirulen rg.ttf'

<OtherLabel@Label>:
    font_size: 12
    bold: True
    color: 0.396078431, 0.803921569, 0.807843137, 1
    font_name: '/home/jarren/PycharmProjects/BCO_Form_Filler/practice/pirulen rg.ttf'
    text_size: self.size

<Button@Button>:
    font_size: 20
    bold: True
    color: 0.396078431, 0.803921569, 0.807843137, 1
    font_name: '/home/jarren/PycharmProjects/BCO_Form_Filler/practice/pirulen rg.ttf'
    background_color: 0.02745098, 0.074509804, 0.121568627, .01
    canvas.before:
        Color:
            rgba: 0.396078431, 0.803921569, 0.807843137, 1
        Line:
            width: 2
            rectangle: self.x, self.y, self.width, self.height
    on_press: self.background_color = (0.396078431, 0.803921569, 0.807843137, 1)
    on_release: self.background_color = (0.02745098, 0.074509804, 0.121568627, .01)

# TODO: Create a focus behavior to "Tab" between widgets
<TextInput@TextInput>:
    font_size: 12
    color: 0.396078431, 0.803921569, 0.807843137, 1
    font_name: '/home/jarren/PycharmProjects/BCO_Form_Filler/practice/pirulen rg.ttf'
    padding_x: 10
    padding_y: 10
    focus_next: None
    focus_previous: None
    unfocus_on_touch: True
    background_color: 0.02745098, 0.074509804, 0.121568627, .01
    canvas.before:
        Color:
            rgba: 0.396078431, 0.803921569, 0.807843137, 1
        Line:
            width: 1
            rectangle: self.x, self.y, self.width, self.height

<TitleScreen>:
    id: "title"
    FloatLayout:
        MainLabel:
            text: "Easy Button"
            size_hint_x: 1
            size_hint_y: 1.25

        SubLabel:
            text: 'Test'
            size_hint_x: 1
            size_hint_y: 1
        Button:
            text: "Click Here To Continue"
            on_release: app.root.current = "main"
            size_hint: (.75, .15)
            pos_hint: {'x': .12, 'y': .2}

<MainScreen>:
    name: "main"
    MainLabel:
        text: "Home Page"
    BoxLayout:
        Button:
            on_release: app.root.current = "create_profile"
            text: "Create Profile"
            size_hint: (.5, .15)
        Button:
            on_release: app.root.current = "create_packet"
            text: "Create Packet"
            size_hint: (.5, .15)

<CreateProfile>:
    name: "create_profile"

    AnchorLayout:
        anchor_x: 'center'
        anchor_y: 'top'
        MainLabel:
            text: "Create Profile"
            size_hint: (1, .15)

    BoxLayout:
        size_hint: (.95, .2)
        pos_hint: {'x': 0, 'y': .85}
        spacing: 10
        padding: 10
        halign: "left"

        OtherLabel:
            text: "First"

        OtherLabel:
            text: "Middle"

        OtherLabel:
            text: "Last"

    BoxLayout:
        size_hint: (.95, .07)
        pos_hint: {'x': 0, 'y': .8}
        spacing: 20
        padding: 10
        halign: "right"
        text_size: self.size

        TextInput:
            id: 'First'


        TextInput:
            id: "Middle"


        TextInput:
            id: 'Last'    

    BoxLayout:

        Button:
            on_release: app.root.current = "main"
            text: "back Home"
            size_hint: (.5, .15)
        Button:
            on_release: root.save()
            text: "Save Profile"
            size_hint: (.5, .15)

<CreatePacket>:
    name: "create_packet"
    MainLabel:
        text: "Select Packet"
    FloatLayout:
        Button:
            on_release: app.root.current = "main"
            text: "back Home"
            size_hint: (1, .15)

Ответы [ 2 ]

0 голосов
/ 15 января 2019

Я нашел обходной путь, который все еще позволяет мне добавлять информацию в JSON с помощью TinyDB. Вот обновленный код:

from kivy.app import App
from kivy.storage.jsonstore import JsonStore
from kivy.lang import Builder
from kivy.uix.screenmanager import Screen, ScreenManager
from kivy.core.window import Window
from tinydb import TinyDB, Query
from kivy.uix.listview import ListItemButton


Window.clearcolor = (0.02745098, 0.074509804, 0.121568627, 1)
Window.size = (2000, 900)

db = TinyDB('bcodb.json')

class ProfileListButton(ListItemButton):
    pass

class TitleScreen(Screen):
    pass

class MainScreen(Screen):
    pass

class CreateProfile(Screen):
    def __init__(self, **kwargs):
        super(CreateProfile, self).__init__(**kwargs)
        self.store = JsonStore("bcodb.json")

    def save(self):
        db.insert({'first': self.first.text, 'middle': self.middle.text, 'last': self.last.text})

    def update(self):
        db.update({'first': self.first.text, 'middle': self.middle.text, 'last': self.last.text})

class CreatePacket(Screen):
    pass

class ScreenManagement(ScreenManager):
    pass


presentation = Builder.load_file("customwidget2.kv")

class CustomWidgetApp(App):
    def build(self):
        return presentation

if __name__ == "__main__":
    CustomWidgetApp().run()

Довольно просто разобраться с простой программой, похожей на базу данных, которую я пытаюсь разработать. Файл .kv такой же.

0 голосов
/ 10 января 2019

В вашем коде есть несколько проблем, но основная из них заключается в том, что вы не понимаете, как открыть какой-либо виджет .kv для .py. Один из самых простых способов - использовать ObjectProperty при попытке сделать это, но это свойство не связано виджету я предпочитаю делать создание в .kv для его простоты.

С другой стороны, я рекомендую вам избегать злоупотребления попыткой, за исключением случаев, когда он скрывает ошибки, лучше всего проверить.

Другая ошибка заключается в том, что вы перезаписываете значение профиля в .json, идея состоит в том, чтобы сохранить все в одном.

Учитывая вышеизложенное, решение:

*. Py

from kivy.app import App
from kivy.storage.jsonstore import JsonStore
from kivy.lang import Builder
from kivy.uix.screenmanager import Screen, ScreenManager
from kivy.core.window import Window
from kivy.clock import Clock


Window.clearcolor = (0.02745098, 0.074509804, 0.121568627, 1)
Window.size = (2000, 900)

class TitleScreen(Screen):
    pass

class MainScreen(Screen):
    pass

class CreateProfile(Screen):
    def __init__(self, **kwargs):
        super(CreateProfile, self).__init__(**kwargs)
        self.store = JsonStore("bco.json")
        Clock.schedule_once(lambda *args: self.load())

    def save(self):
        self.store.put('profile', 
            first = self.first.text,
            middle = self.middle.text,
            last = self.last.text)

    def load(self):
        if self.store.exists('profile'):
            profile = self.store.get('profile')
            v = [("first", self.first), ("middle", self.middle), ("last", self.last)]
            for key, ti in v:
                val = profile.get(key)
                if val:
                    ti.text = val

class CreatePacket(Screen):
    pass

class ScreenManagement(ScreenManager):
    pass

presentation = Builder.load_file("customwidget.kv")

class CustomWidgetApp(App):
    def build(self):
        return presentation

if __name__ == "__main__":
    CustomWidgetApp().run()

*. Киловольт

#: import FadeTransition kivy.uix.screenmanager.FadeTransition
#: import hex kivy.utils.get_color_from_hex
#: import FocusBehaviors kivy.uix.behaviors.focus

ScreenManagement:
    transition: FadeTransition()
    TitleScreen:
    MainScreen:
    CreateProfile:
    CreatePacket:

<MainLabel@Label>:
    font_size:50
    bold: True
    size_hint_x: 1
    size_hint_y: 1.85
    color: 0.396078431, 0.803921569, 0.807843137, 1
    font_name: '/home/jarren/PycharmProjects/BCO_Form_Filler/practice/pirulen rg.ttf'

<SubLabel@Label>:
    font_size: 35
    bold: True
    halign: "center"
    size_hint_x: 1
    size_hint_y: 1.5
    color: 0.396078431, 0.803921569, 0.807843137, 1
    font_name: '/home/jarren/PycharmProjects/BCO_Form_Filler/practice/pirulen rg.ttf'

<OtherLabel@Label>:
    font_size: 12
    bold: True
    color: 0.396078431, 0.803921569, 0.807843137, 1
    font_name: '/home/jarren/PycharmProjects/BCO_Form_Filler/practice/pirulen rg.ttf'
    text_size: self.size

<Button@Button>:
    font_size: 20
    bold: True
    color: 0.396078431, 0.803921569, 0.807843137, 1
    font_name: '/home/jarren/PycharmProjects/BCO_Form_Filler/practice/pirulen rg.ttf'
    background_color: 0.02745098, 0.074509804, 0.121568627, .01
    canvas.before:
        Color:
            rgba: 0.396078431, 0.803921569, 0.807843137, 1
        Line:
            width: 2
            rectangle: self.x, self.y, self.width, self.height
    on_press: self.background_color = (0.396078431, 0.803921569, 0.807843137, 1)
    on_release: self.background_color = (0.02745098, 0.074509804, 0.121568627, .01)

# TODO: Create a focus behavior to "Tab" between widgets
<TextInput@TextInput>:
    font_size: 12
    color: 0.396078431, 0.803921569, 0.807843137, 1
    font_name: '/home/jarren/PycharmProjects/BCO_Form_Filler/practice/pirulen rg.ttf'
    padding_x: 10
    padding_y: 10
    focus_next: None
    focus_previous: None
    unfocus_on_touch: True
    background_color: 0.02745098, 0.074509804, 0.121568627, .01
    canvas.before:
        Color:
            rgba: 0.396078431, 0.803921569, 0.807843137, 1
        Line:
            width: 1
            rectangle: self.x, self.y, self.width, self.height

<TitleScreen>:
    id: "title"
    FloatLayout:
        MainLabel:
            text: "Easy Button"
            size_hint_x: 1
            size_hint_y: 1.25

        SubLabel:
            text: 'Test'
            size_hint_x: 1
            size_hint_y: 1
        Button:
            text: "Click Here To Continue"
            on_release: app.root.current = "main"
            size_hint: (.75, .15)
            pos_hint: {'x': .12, 'y': .2}

<MainScreen>:
    name: "main"
    MainLabel:
        text: "Home Page"
    BoxLayout:
        Button:
            on_release: app.root.current = "create_profile"
            text: "Create Profile"
            size_hint: (.5, .15)
        Button:
            on_release: app.root.current = "create_packet"
            text: "Create Packet"
            size_hint: (.5, .15)

<CreateProfile>:
    name: "create_profile"

    first: first
    middle: middle
    last: last

    AnchorLayout:
        anchor_x: 'center'
        anchor_y: 'top'
        MainLabel:
            text: "Create Profile"
            size_hint: (1, .15)

    BoxLayout:
        size_hint: (.95, .2)
        pos_hint: {'x': 0, 'y': .85}
        spacing: 10
        padding: 10
        halign: "left"

        OtherLabel:
            text: "First"

        OtherLabel:
            text: "Middle"

        OtherLabel:
            text: "Last"
    BoxLayout:
        size_hint: (.95, .07)
        pos_hint: {'x': 0, 'y': .8}
        spacing: 20
        padding: 10
        halign: "right"
        text_size: self.size
        TextInput:
            id: first
        TextInput:
            id: middle
        TextInput:
            id: last    

    BoxLayout:
        Button:
            on_release: app.root.current = "main"
            text: "back Home"
            size_hint: (.5, .15)
        Button:
            on_release: root.save()
            text: "Save Profile"
            size_hint: (.5, .15)

<CreatePacket>:
    name: "create_packet"
    MainLabel:
        text: "Select Packet"
    FloatLayout:
        Button:
            on_release: app.root.current = "main"
            text: "back Home"
            size_hint: (1, .15)
...