Ошибка при хранении данных в файле JSON в KivyMD Python

#python #json #database #kivy #kivymd

Вопрос:

Я попытался сохранить имя пользователя, взятое у пользователя, в .json файле. Но это не работает должным образом. После того, как пользователь повторно вводит имя пользователя, оно случайным образом сохраняется в файле json. Пожалуйста, решите проблему с этим кодом.

  • Иногда .json файл создается случайным образом. Но не в первый раз.

файл .kv

 screen_helper = """
ScreenManager:
    SetUpWindow:
    Home:

<SetUpWindow>:
    name: 'settingup'
    MDTextField:
        id:username_text_fied
        pos_hint: {'center_x':0.5,'center_y':0.45}
        size_hint: (0.7,0.1)
        hint_text : 'Name your Studio'
        helper_text: 'Required'
        helper_text_mode: 'on_focus'
        icon_right: 'account'
        icon_right_color: app.theme_cls.primary_light
        required : True
    MDRaisedButton:
        id:disabled_button
        disabled: True
        text:"Next"
        md_bg_color:app.theme_cls.primary_color
        pos_hint: {'center_x':0.9,'center_y':0.08}
        font_style: 'Button'
        ripple_rad_default : 40
        ripple_duration_out : 1
        md_bg_color: app.theme_cls.primary_dark
        on_press:
            root.manager.current = 'home'
            root.manager.transition.direction = 'left'   

<Home>:
    name: 'home'
"""
 

файл .py

 from kivy.lang.builder import Builder
from kivy.uix.screenmanager import Screen, ScreenManager
from kivymd.app import MDApp
from kivy.storage.jsonstore import JsonStore

class SetUpWindow(Screen):
    pass

sm = ScreenManager()
sm.add_widget(SetUpWindow(name='settingup'))

class Mode(MDApp):
    def build(self):
        screen = Screen()
        self.screen = Builder.load_string(screen_helper)
        screen.add_widget(self.screen)
        self.username_text = self.screen.get_screen('settingup').ids.username_text_fied.text

        return screen


        self.store.put('UserInfo', name=self.username_text)
        self.username_changer()

    def username_changer(self):
        self.screen.get_screen('home').ids.bottomappbar.title = f"Studio {self.store.get('UserInfo')['name']}"


    def on_start(self):
        self.store = JsonStore("std_profile.json")
        try:
            if self.store.get('UserInfo')['name'] != "":
                self.username_changer()
                self.screen.get_screen('home').manager.current = 'home'

        except KeyError:
            self.screen.get_screen('settingup').manager.current = 'settingup'
            
Mode().run()
 

Комментарии:

1. Всего несколько комментариев. Не уверен, что это имеет какое-либо отношение к вашей проблеме. Строки в вашем build() методе после return никогда не будут выполнены. И ваш build() метод строит ваш App как Screen содержащий a ScreenManager , который содержит еще два Screens . Это ваше намерение? Как правило ScreenManager , так оно и есть root . А также в вашем build() методе вы назначаете self.username_text из a Screen , с которым у пользователя не было возможности взаимодействовать.

2. Вы также строите большую часть своего App дважды. Линии sm = ScreenManager() и sm.add_widget(SetUpWindow(name='settingup')) являются составной частью того, что также встроено в Builder.load_string(screen_helper) линию.

3. @JohnAnderson — Спасибо, сэр, за комментарий. На самом деле я новичок. Как вы рекомендуете успешно и правильно написать этот код? Можете ли вы привести мне пример?

Ответ №1:

Вот измененная версия вашего кода, которая делает то, что, я думаю, вы хотите:

 from kivy.lang.builder import Builder
from kivy.uix.screenmanager import Screen
from kivymd.app import MDApp
from kivy.storage.jsonstore import JsonStore

screen_helper = """
ScreenManager:
    SetUpWindow:
    Home:

<SetUpWindow>:
    name: 'settingup'
    MDTextField:
        id:username_text_fied
        pos_hint: {'center_x':0.5,'center_y':0.45}
        size_hint: (0.7,0.1)
        hint_text : 'Name your Studio'
        helper_text: 'Required'
        helper_text_mode: 'on_focus'
        icon_right: 'account'
        icon_right_color: app.theme_cls.primary_light
        required : True
        on_text:
            disabled_button.disabled = False  # enable next button
    MDRaisedButton:
        id:disabled_button
        disabled: True
        text:"Next"
        md_bg_color:app.theme_cls.primary_color
        pos_hint: {'center_x':0.9,'center_y':0.08}
        font_style: 'Button'
        ripple_rad_default : 40
        ripple_duration_out : 1
        md_bg_color: app.theme_cls.primary_dark
        on_press:
            app.save_user_name()  # save user name to Json
            root.manager.current = 'home'
            root.manager.transition.direction = 'left'   

<Home>:
    name: 'home'
    MDBottomAppBar:
        MDToolbar:
            id: bottomappbar
            title: "Title"
            icon: "git"
            type: "bottom"
            left_action_items: [["menu", lambda x: x]]
            mode: "free-end"
"""

class SetUpWindow(Screen):
    pass


class Home(Screen):
    pass


class Mode(MDApp):
    def build(self):
        return Builder.load_string(screen_helper)

    def save_user_name(self):  # added method to actually save user name to JSon
        self.username_text = self.root.get_screen('settingup').ids.username_text_fied.text
        self.store.put('UserInfo', name=self.username_text)
        self.username_changer()

    def username_changer(self):
        self.root.get_screen('home').ids.bottomappbar.title = f"Studio {self.store.get('UserInfo')['name']}"

    def on_start(self):
        self.store = JsonStore("std_profile.json")
        try:
            if self.store.get('UserInfo')['name'] != "":
                self.username_changer()
                self.root.get_screen('home').manager.current = 'home'

        except KeyError as e:
            self.root.get_screen('settingup').manager.current = 'settingup'


Mode().run()
 

Обратите внимание на изменение build() метода и исключение другого кода, который создавался ScreenManager и SetUpWindow . Ссылки, которые должны self.screen были быть заменены на self.root . Next Кнопка теперь сохраняет имя пользователя.