Как мне указать кнопку, которую я хочу активировать? - PullRequest
0 голосов
/ 24 апреля 2019

Когда я нажимаю кнопку, вызывается функция check_streak(). Я хочу только сравнить это время кнопок ака «мед» с time.time(). Вместо того, чтобы печатать ответ на одну кнопку «honey», сравниваются все кнопки «honey», и для каждой из них печатается ответ. Поскольку кнопка создается в цикле for, я не уверен, как я могу указать, что хочу сравнивать только эту конкретную кнопку. Как бы я это исправить? код:

class MainApp(App):

    def build(self): # build() returns an instance
        self.store = JsonStore("streak.json") # file that stores the streaks:


        return presentation

    # Gets the value of delta (code I may never understand lol)
    def item_generator(self, json_input, lookup_key):
        if isinstance(json_input, dict):
            for k, v in json_input.items():
                if k == lookup_key:
                    yield v
                else:
                    yield from self.item_generator(v, lookup_key)
        elif isinstance(json_input, list):
            for item in json_input:
                yield from self.item_generator(item, lookup_key)

    def check_streak(self, instance):
        with open("streak.json", "r") as read_file:
            data = json.load(read_file)
            values = self.item_generator(data, 'delta')



        for honey in values:
            if honey > time.time():
                print("early")

            if honey == time.time():
                print("on time")

            if honey < time.time():
                print("late")
def display_btn(self):
        # display the names of the streaks in a list on PageTwo
        for key in self.store:
            streak_button = Button(text=key, on_press=self.check_streak)
            self.root.screen_two.ids.streak_zone.add_widget(streak_button)

В настоящее время у меня есть 3 кнопки в программе. Когда я нажимаю кнопку, я ожидаю печатать «рано», но вместо этого я печатаю «рано рано рано», потому что есть 3 кнопки.

1 Ответ

0 голосов
/ 24 апреля 2019

Kivy Widget »всплывающее окно с сенсорным событием

Когда вы ловите сенсорные события между несколькими виджетами, вам часто нужно знать порядок, в котором эти события распространяются. В Киви, события всплывают от первого ребенка вверх через другого дети. Если у виджета есть дети, событие передается через его дети до того, как их передают виджету после него.

Kivy »Основы сенсорных событий

По умолчанию сенсорные события отправляются всем отображаемым в данный момент виджеты. Это означает, что виджеты получают событие касания, происходит ли оно в пределах их физической области или нет.

...

Чтобы обеспечить максимальную гибкость, Kivy отправляет события для всех виджетов и позволяет им решать, как реагировать на них. Если вы хотите отвечать только на сенсорные события внутри виджета, вы просто проверьте:

def on_touch_down(self, touch):
    if self.collide_point(*touch.pos):
        # The touch has occurred inside the widgets area. Do stuff!
        pass

Решение

  • Создать class CustomButton с наследованием Button
  • Реализация on_touch_down метод
  • Проверка на столкновение с использованием функции collide_point()

Отрывки

class CustomButton(Button):
    def on_touch_down(self, touch):
        if self.collide_point(*touch.pos):
            self.dispatch('on_press')
            return True
        return super(CustomButton, self).on_touch_down(touch)    
...

    def display_btn(self):
        # display the names of the streaks in a list on PageTwo
        with open("streak.json", "r") as read_file:
            data = json.load(read_file)

            for value in self.item_generator(data, 'delta'):
                print(f"\tvalue={value}")
                streak_button = CustomButton(text=str(value), on_press=self.check_streak)
            self.root.screen_two.ids.streak_zone.add_widget(streak_button)

Пример

Следующий пример иллюстрирует предлагаемое решение.

main.py

from kivy.app import App
from kivy.uix.screenmanager import Screen
from kivy.uix.button import Button
from kivy.storage.jsonstore import JsonStore
from kivy.lang import Builder
from kivy.clock import Clock
import time
import json


class ScreenTwo(Screen):
    pass


Builder.load_string("""
<ScreenTwo>:
    GridLayout:
        id: streak_zone
        cols: 2
""")


class CustomButton(Button):
    def on_touch_down(self, touch):
        if self.collide_point(*touch.pos):
            print(f"\nCustomButton.on_touch_down: text={self.text}")
            self.dispatch('on_press')
            return True
        return super(CustomButton, self).on_touch_down(touch)


class TestApp(App):
    def build(self):
        self.store = JsonStore("streak.json")
        Clock.schedule_once(lambda dt: self.display_btn(), 0.5)

        return ScreenTwo()

    def check_streak(self, instance):
        print(f"\ncheck_streak:")
        honey = float(instance.id)
        print(f"\tdelta={honey}")
        if honey > time.time():
            print("\t\tearly")

        if honey == time.time():
            print("\t\ton time")

        if honey < time.time():
            print("\t\tlate")

    def display_btn(self):
        print(f"\ndisplay_btn:")

        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']}")
                    streak_button = CustomButton(id=str(value['delta']), text=value['action'], on_press=self.check_streak)
                    self.root.ids.streak_zone.add_widget(streak_button)


if __name__ == '__main__':
    TestApp().run()
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...