Переместить окно Kivy путем перетаскивания метки - Kivy, Python

Я хочу создать пользовательский заголовок окна Kivy. Я очень новичок в kivy, поэтому, пожалуйста, предоставьте некоторые объяснения, как работают события. Мне нужно просто переместить окно, "перемещая" метку.

Прежде всего я хочу знать, почему это вызывает любую функцию, когда я щелкаю или перетаскиваю ярлык. Это в KvLang:

#:import main main.window

CustBoxLayout:
<CustBoxLayout>:
    orientation: 'vertical'

    Label:
        id: header
        text: 'MyApp'
        font_size: 24
        padding_x: 16
        color: self.theme_cls.primary_color

        on_touch_down: main.click
        on_touch_move: main.move

...

Любая функция не вызывается, когда я нажимаю или перетаскиваю метку. Однако если я изменю main.click например print('touched!') оно работает.

Итак, я создал свой собственный класс:

class HeadLabel(MaterialLabel):
    def on_touch_down(self, touch):
        window.click(touch)

    def on_touch_move(self, touch):
        window.drag(touch)

Это работает. Но теперь я не знаю, как получить положение экрана из MotionEvent событие. Это мой фактический код окна:

class WindowApp(App):
    theme_cls = ThemeManager()

    def build(self):
        self.theme_cls.theme_style = 'Light'
        self.theme_cls.primary_palette = 'Purple'

        return CustBoxLayout()

    def click(self, touch):
        self.touch_x, self.touch_y = touch.spos[0], touch.spos[1]

    def drag(self, touch):
        Window.top = self.touch_y + touch.spos[0]
        Window.left = self.touch_x + touch.spos[1])

Любая помощь будет высоко оценена.

1 ответ

Решение

Определите класс для пользовательской метки и реализуйте методы on_touch_down и on_touch_move. Пожалуйста, обратитесь к примеру ниже для деталей.

Руководство по программированию "Управление вводом" Основы сенсорных событий

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

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

пример

main.py

from kivy.app import App
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.label import Label
from kivy.core.window import Window
from kivymd.theming import ThemeManager


class CustomLabel(Label):

    def on_touch_down(self, touch):
        print("\nCustomLabel.on_touch_down:")

        if self.collide_point(*touch.pos):
            print("\ttouch.pos =", touch.pos)
            self.touch_x, self.touch_y = touch.spos[0], touch.spos[1]
            return True
        return super(CustomLabel, self).on_touch_down(touch)

    def on_touch_move(self, touch):
        print("\nCustomLabel.on_touch_move:")

        if self.collide_point(*touch.pos):
            print("\ttouch.pos =", touch.pos)
            Window.top = self.touch_y + touch.spos[0]
            Window.left = self.touch_x + touch.spos[1]
            return True
        return super(CustomLabel, self).on_touch_move(touch)


class CustBoxLayout(BoxLayout):
    pass


class TestApp(App):
    theme_cls = ThemeManager()

    def build(self):
        self.theme_cls.theme_style = 'Light'
        self.theme_cls.primary_palette = 'Purple'

        return CustBoxLayout()


if __name__ == "__main__":
    TestApp().run()

test.kv

#:kivy 1.10.0

<CustomLabel>:


<CustBoxLayout>:
    orientation: 'vertical'

    CustomLabel:
        id: header
        text: 'MyApp'
        font_size: 24
        padding_x: 16
        color: app.theme_cls.primary_color

    Button:
        text: 'Button Widget'
        font_size: 24
        padding_x: 16
        color: app.theme_cls.primary_color

Выход

Img01 - при касании Img02 - на ощупь

Другие вопросы по тегам