kivy обнаруживает клики по виджетам на экране - PullRequest
0 голосов
/ 18 июня 2020

У меня есть экран с несколькими виджетами внутри. Мне нужно определить, нажал ли пользователь метку - «домой»

Каждый раз, когда я нажимаю на экран, запускаются on_touch_down и on_touch_up. как определить метку, по которой я щелкнул ..

class WordScreen(Screen):
    def __init__(self, **kwargs):
        label_text = kwargs['label_text']
        del kwargs['label_text']
        super(WordScreen, self).__init__(**kwargs)

        main_layout = BoxLayout(id='test', orientation='vertical')
        navigation_layout = BoxLayout(orientation='horizontal',
                                      size_hint_y=.1)
        navigation_layout.add_widget(Label(text='home'))
        navigation_layout.add_widget(Label(text='audio'))
        navigation_layout.add_widget(Label(text='favorite'))
        text_layout = BoxLayout(orientation='vertical')
        text_layout.add_widget(Label(id='sight_text', text=label_text))
        main_layout.add_widget(navigation_layout)
        main_layout.add_widget(text_layout)

        self.add_widget(main_layout)

    def on_touch_down(self, touch):
        self.initial = touch.x

    def on_touch_up(self, touch):
        print('on_touch_up - ', touch.x)

        print(self.collide_point(*touch.pos))
        print(touch.button)
        s = None
        try:
            s = self.manager.get_screen('settings')
        except ScreenManagerException:
            pass
        print('screen - ', s)
        if s is not None:
            self.manager.clear_widgets([s])
        print('screen removed')
        if touch.x < self.initial:
            self.manager.transition = SlideTransition(direction="right")
            self.manager.current = self.manager.next()
        elif touch.x > self.initial:

            self.manager.transition = SlideTransition(direction="right")
            self.manager.current = self.manager.previous()

1 Ответ

0 голосов
/ 18 июня 2020

На основе ссылки из комментария Джона Андерсона я создал интерактивную метку.

from kivy.app import App
from kivy.uix.label import Label
from kivy.uix.behaviors import ButtonBehavior


class MyLabel(ButtonBehavior, Label):

    def on_press(self):
        print("press:", self.text)

    def on_release(self):
        print("release:", self.text)


class MyApp(App):
    def build(self):
        return MyLabel(text="Hello")


MyApp().run()

Но проблема может заключаться в том, что on_touch_down и on_touch_up могут блокировать другие события и тогда даже стандартный Button работать не будет. Возможно, вам придется проверять on_touch_down и on_touch_up только в виджете, который не требует on_press, on_release

Вероятно, это можно было бы решить, используя только on_touch_move без on_touch_down, on_touch_up


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

Минимальный рабочий код.

Он использует интерактивную метку и on_touch_move без on_touch_down, on_touch_up для слайд-экрана.

Кстати: я использую if touch.dx < -3: вместо if touch.dx < 0:, чтобы пропустить очень маленькие ходы. Я тестировал его только с помощью мыши, но для поисковиков может потребоваться другое значение.

from kivy.uix.boxlayout import BoxLayout
from kivy.app import App
from kivy.uix.button import Button
from kivy.uix.label import Label
from functools import partial

from kivy.uix.screenmanager import ScreenManager, Screen, SlideTransition

from kivy.uix.behaviors import ButtonBehavior


class MyLabel(ButtonBehavior, Label):

    def on_press(self):
        print("pressed:", self.text)

    def on_release(self):
        print("release:", self.text)


class WordScreen(Screen):

    def __init__(self, **kwargs):
        label_text = kwargs['label_text']
        del kwargs['label_text']

        super(WordScreen, self).__init__(**kwargs)

        main_layout = BoxLayout(id='test', orientation='vertical')
        navigation_layout = BoxLayout(orientation='horizontal',
                                      size_hint_y=.1)

        navigation_layout.add_widget(MyLabel(text='home'))
        navigation_layout.add_widget(MyLabel(text='audio'))
        navigation_layout.add_widget(MyLabel(text='favorite'))

        text_layout = BoxLayout(orientation='vertical')
        #text_layout.add_widget(Label(id='sight_text', text=label_text))
        text_layout.add_widget(Label(id='sight_text', text=self.name))

        main_layout.add_widget(navigation_layout)
        main_layout.add_widget(text_layout)

        self.add_widget(main_layout)

    def on_touch_move(self, touch):
        #print('touch variable:\n', "\n".join(dir(touch)))
        print('touch.dx:', touch.dx)
        print('touch.dsx:', touch.dsx)
        #print('touch.distance:', touch.distance)
        #print('touch.move:', touch.move)

        if touch.dx < -3:   # using `touch.dx < 0` it slides even on very small moves
            self.manager.transition = SlideTransition(direction="right")
            self.manager.current = self.manager.next()
        elif touch.dx > 3:  # using `touch.dx > 0` it slides even on very small moves
            self.manager.transition = SlideTransition(direction="right")
            self.manager.current = self.manager.previous()

sm = ScreenManager()
sm.add_widget(WordScreen(name='menu', label_text="Example"))
sm.add_widget(WordScreen(name='settings', label_text="Example"))

class MyApp(App):

    def build(self):
        return sm

if __name__ == '__main__':
    MyApp().run()

EDIT:

Проблема с on_touch_down, on_touch_up какой блок on_press, on_release может быть разрешен с помощью super() для выполнения исходного кода on_touch_down, on_touch_up

def on_touch_down(self, touch):
    # ... code ...
    return super(WordScreen, self).on_touch_down(touch)

def on_touch_up(self, touch):
    # ... code ...
    return super(WordScreen, self).on_touch_up(touch)

На основе примера в документации: Events - Dispatching a Property событие

...