Search code examples
pythonkivykivy-language

Python kivy double tap


I'm making an App in Python kivy, and I have a draggable Image. Whenever a user double taps on the draggable image it prints "this is a double tap".

main.py

from kivy.app import App
from kivy.uix.screenmanager import Screen
from kivy.clock import Clock
from functools import partial
from kivy.lang import Builder
from kivy.uix.behaviors import DragBehavior
from kivy.uix.image import Image

class DragImage(DragBehavior, Image):
    def on_touch_up(self, touch):
        uid = self._get_uid()
        if uid in touch.ud:
        return super(DragImage, self).on_touch_up(touch)

    def on_touch_down(self, touch):
        if self.collide_point(*touch.pos) and touch.is_double_tap:
            print('this is a double tap')
        return super(DragImage, self).on_touch_down(touch)

class TacScreen(Screen):
    pass


class MainApp(App):
    def build(self):
        return Builder.load_string(kv)


MainApp().run()

Solution

  • If you set your <DragImage> rule in the kv to:

    DragImage
        id: tv
        pos: 0, 102
        size_hint: None, .1
        width: self.height
        source: "Tv.png"
    

    Then the DragImage will stay square and the picture will fill the Image widget (if the Tv.png is a square picture).

    When the Window is resized, the DragImage will stay in the same pos, but will not stay in the same location relative to the background image. One way to keep the DragImage stationary is to use pos_hint, but that will not allow dragging. You can keep the DragImage stationary relative to the background by adding a on_size() method to TacScreen:

    class TacScreen(Screen):
        old_size = ListProperty([800, 600])  # keeps track of previous size
    
        def on_size(self, screen, new_size):
            if self.old_size != new_size:
                di = self.ids.tv  # get the DragImage
                # move the DragImage to keep it stationary relative to background
                di.pos = new_size[0] * di.x / self.old_size[0], new_size[1] * di.y / self.old_size[1]
            self.old_size = new_size