How can I detect when touch is in the children widget in kivy

Question:

How I can detect when touch position in a children widget of game grid? When I want call children method mark_label(). Thank you.

class GameGrid(GridLayout):

    def on_touch_move(self, touch):
        #which label is collision  
        print(str(touch.pos))


class StartScreen(Screen):

    level = Level(mode, 1)

    def __init__(self,**kwargs):
        super().__init__(**kwargs)
        self.create_level()

    def create_level(self):
        self.ids.game_grid.clear_widgets()

        labels = self.level.get_letters_label()
        for f in range(len(labels)):
            self.ids.game_grid.add_widget(labels[f])
Asked By: Mikkey

||

Answers:

Use self.collide_points() method to check for collision of the touch with the widget of interest.

Snippets

class CreateLabel(Label):

def on_touch_down(self, touch):
    if self.collide_point(*touch.pos):
        # TODO
        # call method mark_label()
        if touch.button == "right":
            print("Right mouse clicked on {}".format(self.text))
        elif touch.button == "left":
            print("Left mouse clicked on {}".format(self.text))
        else:
            print(self.id)
        return True
    return super(CreateLabel, self).on_touch_down(touch)

Programming Guide » Events and Properties » Dispatching a Property event

If the touch falls inside of our widget, we change the value of
pressed to touch.pos and return True, indicating that we have consumed
the touch and don’t want it to propagate any further.

Finally,
if the touch falls outside our widget, we call the original event
using super(…) and return the result. This allows the touch event
propagation to continue as it would normally have occurred.

Example

main.py

from kivy.app import App
from kivy.uix.gridlayout import GridLayout
from kivy.uix.label import Label


class CreateLabel(Label):

    def on_touch_down(self, touch):
        if self.collide_point(*touch.pos):
            if touch.button == "right":
                print("Right mouse clicked on {}".format(self.text))
            elif touch.button == "left":
                print("Left mouse clicked on {}".format(self.text))
            else:
                print(self.id)
            return True
        return super(CreateLabel, self).on_touch_down(touch)


class RootWidget(GridLayout):

    def __init__(self, **kwargs):
        super(RootWidget, self).__init__(**kwargs)
        self.build_board()

    def build_board(self):
        # make 9 label in a grid
        for i in range(0, 9):
            label = CreateLabel(id=str(i), text="Label {}".format(i))
            self.add_widget(label)


class TestApp(App):

    def build(self):
        return RootWidget()


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

test.kv

#:kivy 1.10.0

<CreateLabel>:
    canvas.before:
        Color:
            rgba: 0, 1, 1, 0.5  # 50% blue
        Rectangle:
            size: self.size
            pos: self.pos
    font_size: 30
    on_touch_down: self.on_touch_down

<RootWidget>:
    rows: 3
    cols: 3
    row_force_default: True
    row_default_height: 150
    col_force_default: True
    col_default_width: 150
    padding: [10]
    spacing: [10]

Output

Img01 - Clicked on Label 3
Img02 - Clicked on Label 8

Answered By: ikolim
Categories: questions Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.