在Kivy中使用jsonstore

2024-09-28 05:41:50 发布

您现在位置:Python中文网/ 问答频道 /正文

我创建了一个基于this question的GUI,同时试图自学如何使用jsonstore。我没有声誉点来添加评论,所以我在这里问我的问题。我想我已经掌握了基本概念,但是由于某些原因,我不能将数据保存到json文件中。我得到以下错误:

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

我试着按照文档进行操作,但我看不到任何地方可以解释我做错了什么。在

主.py

^{pr2}$

自定义控件.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)

Tags: textnameselftruehomesizereleaseon
2条回答

您的代码有几个问题,但最主要的一个问题是您不了解如何将任何.kv小部件公开给.py,最简单的方法之一是使用ObjectProperty,但是该属性没有链接到小部件,为了简单起见,我更喜欢在.kv中创建。在

另一方面,我建议你避免滥用try,除非它隐藏了错误,最好的方法是验证。在

另一个错误是您在.json中重写了profile的值,其思想是将所有内容保存在一个文件中。在

考虑到上述情况,解决方案是:

*.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()

*.kv

^{pr2}$

我找到了一个解决方法,它仍然允许我使用TinyDB将信息附加到JSON中。以下是更新后的代码:

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文件是相同的。在

相关问题 更多 >

    热门问题