Estoy confundida sobre touch.grab

Documentación dice

La coordenada táctil no se traduce al espacio de su widget porque el toque proviene directamente de la ventana. Es su trabajo convertir las coordenadas a su espacio local.

Pero cuando ejecuté el código de abajo

# -*- coding: utf-8 -*-

from kivy.base import runTouchApp
from kivy.lang import Builder
from kivy.factory import Factory


class DragRecognizer(Factory.Widget):

    def on_touch_down(self, touch):
        if self.collide_point(*touch.pos):
            touch.grab(self)
            print('on_drag_begin', touch.pos)
            return True
        else:
            return super().on_touch_down(touch)

    def on_touch_up(self, touch):
        if touch.grab_current is self:
            touch.ungrab(self)
            print('on_drag_end', touch.pos, '(grab)')
            return True
        else:
            print('on_drag_end', touch.pos)
            return super().on_touch_up(touch)


root = Builder.load_string(r'''
<Widget>:
    canvas.after:
        Line:
            rectangle: self.x+2,self.y+2,self.width-3,self.height-3
            dash_offset: 5
            dash_length: 3

BoxLayout:
    Widget:
    RelativeLayout
        DragRecognizer:
            size_hint: 0.8, 0.8
            pos_hint: {'center_x': 0.5, 'center_y': 0.5, }
''')

runTouchApp(root)

Y pulsó el botón del ratón.

Captura

Esperaba así

on_drag_begin (88, 111)
on_drag_end (88, 111)
on_drag_end (488, 111) (grab)

Pero lo que tengo es

on_drag_begin (88, 111)
on_drag_end (88, 111)
on_drag_end (88, 111) (grab)

¡El toque agarrado no es coordenadas de ventana! Entonces no entiendo cuál es el punto de la documentación. Perdón por mi mal ingles. Realmente aprecio si me ayudas.

0
Nattōsai Mitō 14 nov. 2017 a las 13:10

2 respuestas

La mejor respuesta

https://github.com/kivy/kivy/pull/5925
La documentación estaba mal. Perdón por responder demasiado tarde.

1
Nattōsai Mitō 14 may. 2020 a las 13:13

Tienes que convertir la coordenada a tu espacio local usando * instancia.to_ventana ( instancia.pos) . Consulte el ejemplo para obtener más detalles.

Retazo

to_window = instance.to_window(*instance.pos)

Ejemplo

Main.py

# -*- coding: utf-8 -*-

from kivy.base import runTouchApp
from kivy.lang import Builder
from kivy.factory import Factory
from kivy.properties import ListProperty


class DragRecognizer(Factory.Widget):
    pressed = ListProperty([0, 0])

    def on_touch_down(self, touch):
        if self.collide_point(*touch.pos):
            touch.grab(self)
            self.pressed = touch.pos
            print('on_touch_down: on_drag_begin', touch.pos)
            return True

    def on_touch_up(self, touch):
        if touch.grab_current is self:
            touch.ungrab(self)
            print('on_touch_up: on_drag_end', touch.pos, '(grab)')
            return True

    def on_pressed(self, instance, pos):
        print("Pressed at {}".format(pos))
        to_window = instance.to_window(*instance.pos)
        print("to_window = {}".format(to_window))
        to_widget = instance.to_widget(*to_window)
        print("to_widget = {}".format(to_widget))


root = Builder.load_string(r'''
<Widget>:
    canvas.after:
        Line:
            rectangle: self.x+2,self.y+2,self.width-3,self.height-3
            dash_offset: 5
            dash_length: 3

BoxLayout:
    Widget:
    RelativeLayout
        DragRecognizer:
            size_hint: 0.8, 0.8
            pos_hint: {'center_x': 0.5, 'center_y': 0.5, }
''')

runTouchApp(root)

Salida

enter image description here

0
ikolim 14 nov. 2017 a las 14:55