Что вызывает сброс файла json после добавления виджета kivy? - PullRequest
0 голосов
/ 05 июня 2019

В моем приложении kivy используются кнопки, и эти кнопки соответствуют элементам json в отдельном файле json.

Это будет кнопка Eight

"Eight": {
        "action": "Eight",
        "delay": 1.55975283E9,
        "seconds": 0,
        "score": 0,
        "delta": 1.55974682E9,
        "grace_sec": 6000
    }

Когда я нажимаю кнопку,Счет будет добавлять значение 1 каждый раз.Однако, когда я добавляю еще одну кнопку, счет сбрасывается до 0.

Я действительно не уверен, что это такое, потому что в какой-то момент мой код этого не сделал.Должно быть, я что-то изменил, не заметив.Я полагаю, что проблема, возможно, связана с функцией store в kivy, но я не уверен.

Я включу весь код, который, по моему мнению, может влиять на файл json.

class MainApp(App):
    def build(self):  # build() returns an instance
        self.store = JsonStore("streak.json")  # file that stores the streaks:
        Clock.schedule_interval(self.check_streak, 1/30.) # used to call functions dynamicaly
        Clock.schedule_interval(self.score_gone, 1/30.)
        Clock.schedule_interval(self.update_high, 1/30.)

        return presentation

Эта функция длиннее, но я включаю только часть, которая добавляет оценку 1.

def check_streak(self, dt):
        for child in reversed(self.root.screen_two.ids.streak_zone.children):
            name = child.id

            with open("streak.json", "r") as read_file:
                data = json.load(read_file)

            for key in data.keys():
                if key == name:
                    delay = data.get(key, {}).get('delay')  # get value of nested key 'delay'
                    self.honey = data[key]['delta']
                    float(self.honey)
                        ...

                elif delay > time.time() > self.honey:  # on time (green)
                    child.background_normal = ''
                    child.background_color = [0, 1, 0, .95]
                    child.unbind(on_press=self.early_click)
                    child.bind(on_press=self.add_score)
                    child.bind(on_press=self.display_streak)
                    child.bind(on_press=self.draw_streak)
                    child.unbind(on_press=self.late_click)

# add 1 to score and store in json file
    def add_score(self, obj):
        name = obj.id

        with open("streak.json", "r") as file:
            read = json.load(file)

        for key in read.keys():
            if key == name:
                with open("streak.json", "r+") as f:
                    data = json.load(f)
                    data[key]['score']+=1

                    grace_sec = data.get(key, {}).get('grace_sec')
                    new_delay = time.time() + grace_sec
                    data[key]['delay'] = new_delay

                    seconds = data.get(key, {}).get('seconds')
                    new_delta = time.time() + seconds
                    data[key]['delta'] = new_delta

                    f.seek(0)
                    json.dump(data, f, indent=4)
                    f.truncate()

Я включаю это, потому что это экземпляр основного приложения и всегда вызываетсяиз-за функции Clock, но я не думаю, что это является причиной проблемы, поэтому вы можете игнорировать, если это так.

# changes score to 0 and stores in json file
def score_gone(self, dt):
        for child in self.root.screen_two.ids.streak_zone.children:
            name = child.id
            color = child.background_color

            with open("streak.json", "r") as file:
                read = json.load(file)

            if color == [1, 0, 0, .95]: # red

                if read[name]['score'] != 0: #stops slow down from Clock
                    with open("streak.json", "r+") as f: # fix score not reseting to 0
                            data = json.load(f)
                            data[name]['score'] = 0
                            f.seek(0)
                            json.dump(data, f, indent=4)
                            f.truncate()

                elif read[name]['score'] == 0: #stops slow down from Clock
                        pass

Это функция, которая создает полосу из ввода текста впредыдущая страница.

    # creates the Streak object
    def create(self):
          ...
            # store streak attributes inside "streak.json"
            self.store.put(self.streak.action, action=self.streak.action,
                           delay=grace, seconds=total,
                           score=0, delta=self.count, grace_sec=grace_sec)

            self.change_screen(self) # changes to screen that displays buttons


Эта функция отображает кнопки.

# display the names of the streaks in a list on PageTwo
    def display_btn(self):
        no_data = "You have no stored streaks!"
        popup_2 = Popup(title="No Streaks!", content=Label(text=no_data),
                        size_hint=(None, None), size=(300, 100))

        with open("streak.json", "r") as read_file:
            data = json.load(read_file)

        for value in data.values():
            if value['delta'] is not None:
                print(f"action={value['action']}, delta={value['delta']}, grace={value['delay']}")
                    streak_button = StreakButton(id=(value['action']), text=(value['action'] + " " + "[" + str(value['score']) + "]"),
                                                 color=(0,0,0,1), size=(400, 50),
                                                 size_hint=(None, None))

                self.root.screen_two.ids.streak_zone.add_widget(streak_button)
...

Все виджеты кнопок удаляются при выходе из страницы и вызывается display_btn при входе на страницу.Что меня странно, так это то, как программа запоминает значение оценки перед добавлением новой кнопки, даже если файл json обновляется до новой оценки.Если бы я добавил 1 балл к кнопке Eight, то закрылся бы из программы;Приложение запомнит, что значение равно 1. Поэтому, если я добавлю значение 2, а затем добавлю новую кнопку, значение Eight будет сброшено до 1, поскольку это было его значение до того, как я закрыл приложение.

РЕДАКТИРОВАТЬ

Это весь код в create, который используется для сбора данных из текстового ввода внутри страницы.Математика, которую вы видите, просто превращает ввод в секунды для более поздней функции, которая сравнивает время (я не уверен, если это необходимо)

def create(self):
        obj = self.root.get_screen('one')  # get info from ScreenOne
        self.streak = Streak(obj.ids.action_entry.text, obj.ids.delay_entry.text,
                             obj.ids.day_entry.text, obj.ids.hour_entry.text,
                             obj.ids.minute_entry.text)

        empty_error = "Make sure to fill out all boxes!"  # not in use yet

        popup = Popup(title="Not filled", content=Label(text=empty_error),
                      size_hint=(None, None), size=(300, 100))

        # error handling and calculating total seconds
        parsed = False
        try:
            total = ((int(self.streak.day) * 86400) + (int(self.streak.hour) * 3600) +
                     (int(self.streak.minute) * 60))  # convert into seconds

            self.current_time = time.time()
            self.count = self.current_time + total
            grace = (int(self.streak.delay) * 60) + self.count  # aka delay
            grace_sec = (int(self.streak.delay) * 60) + total

            parsed = True

            # delete later just used to test
            print("[seconds:", total, ']', "[action:", self.streak.action, ']',
                  "[grace:", grace, ']')

            # store streak attributes inside "streak.json"
            self.store.put(self.streak.action, action=self.streak.action,
                           delay=grace, seconds=total,
                           score=0, delta=self.count, grace_sec=grace_sec)

            self.change_screen(self)
        except ValueError as error:
            popup.open()

create использует экземпляр Streak

class Streak():
    def __init__(self, action, delay, day, hour, minute, score=0, delta=0):
        self.action = action
        self.delay = delay
        self.day = day
        self.hour = hour
        self.minute = minute
        self.score = score
        self.delta = delta

Ответы [ 2 ]

1 голос
/ 05 июня 2019

Файл JSON сбрасывается, поскольку self.store был заполнен в методе build() изображением перед добавлением.Добавьте self.store = JsonStore("streak.json") в create() метод.

Фрагменты

def create(self):
    self.store = JsonStore("streak.json") 
0 голосов
/ 05 июня 2019

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...