Kivy Canvas redrawing after touch event

kivy, python

Solution

As this question got more views as I excepted, I leave here a working example:

from kivy.app import App
from kivy.logger import Logger
from kivy.graphics import Color, Ellipse, Line
from kivy.uix.boxlayout import BoxLayout


class CustomLayout(BoxLayout):

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

        self.canvas_edge = {}
        self.canvas_nodes = {}
        self.nodesize = [25, 25]

        self.grabbed = {}

        #declare a canvas
        with self.canvas.after:
            pass

        self.define_nodes()
        self.canvas.add(self.canvas_nodes[0])
        self.canvas.add(self.canvas_nodes[1])
        self.define_edge()
        self.canvas.add(self.canvas_edge)



    def define_nodes(self):
        """define all the node canvas elements as a list"""

        self.canvas_nodes[0] = Ellipse(
            size = self.nodesize,
            pos =  [100,100]
            )

        self.canvas_nodes[1] = Ellipse(
            size = self.nodesize,
            pos =  [200,200]
            )

    def define_edge(self):
        """define all the edge canvas elements as a list"""


        self.canvas_edge = Line(
            points =  [
                self.canvas_nodes[0].pos[0] + self.nodesize[0] / 2,
                self.canvas_nodes[0].pos[1] + self.nodesize[1] / 2,
                self.canvas_nodes[1].pos[0] + self.nodesize[0] / 2,
                self.canvas_nodes[1].pos[1] + self.nodesize[1] / 2
                ],
            joint = 'round',
            cap = 'round',
            width = 3
            )


    def on_touch_down(self, touch):

        for key, value in self.canvas_nodes.items():
            if (value.pos[0] - self.nodesize[0]) <= touch.pos[0] <= (value.pos[0] + self.nodesize[0]):
                if (value.pos[1] - self.nodesize[1]) <= touch.pos[1] <= (value.pos[1] + self.nodesize[1]):
                    touch.grab(self)
                    self.grabbed = self.canvas_nodes[key]
                    return True

    def on_touch_move(self, touch):

        if touch.grab_current is self:
            self.grabbed.pos = [touch.pos[0] - self.nodesize[0] / 2, touch.pos[1] - self.nodesize[1] / 2]
            self.canvas.clear()
            self.canvas.add(self.canvas_nodes[0])
            self.canvas.add(self.canvas_nodes[1])
            self.define_edge()
            self.canvas.add(self.canvas_edge)
        else:
            # it's a normal touch
            pass

    def on_touch_up(self, touch):
        if touch.grab_current is self:
            # I receive my grabbed touch, I must ungrab it!
            touch.ungrab(self)
        else:
            # it's a normal touch
            pass

class MainApp(App):

    def build(self):
        root = CustomLayout()
        return root

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

Problem

I wanna make a small game, but I need some help... I'm pretty newbie both in python and in kivy. I'm using python 3.4 and kivy 1.8.0. The game will have some drawn elements which will be draggable and/or disappering: -if you click on a point you could drag it - if you click anywhere one point will disappear I've tried to make the disappearing part of it, but I got stuck. I made a dummy code with some points on the canvas, where you could see how I wanted to approach the problem: --> draw some points --> remove / reposition one of point --> clear canvas --> redraw Somehow I cannot redraw it. But I managed to clear the canvas... Could you help me? Also I would like to get help/ideas how to make it draggable... Thank you, here's my code: ``` from kivy.app import App from kivy.graphics import Ellipse from kivy.uix.boxlayout import BoxLayout import random class CustomLayout(BoxLayout): def __init__(self, **kwargs): super(CustomLayout, self).__init__(**kwargs) self.a = [] self.points_pos() with self.canvas.after: self.draw_points() def points_pos(self): i=0 x = random.sample(range(800), 10) y = random.sample(range(640), 10) for i in range(10): pos = [0,0] pos[0]=x[i] pos[1]=y[i] self.a.append(pos) print(self.a) def draw_points(self): i = 0 for i in range(len(self.a)): self.circle = Ellipse( size = (25,25), pos = (self.a[i][0],self.a[i][1]) ) def random_remove(self): point = self.a[random.randint(0,len(self.a)-1)] self.a.remove(point) def update(self): self.parent.canvas.clear() with self.canvas: self.draw_points() def on_touch_down(self, touch): self.random_remove() self.update() class MainApp(App): def build(self): root = CustomLayout() return root if __name__ == '__main__': MainApp().run() ```

Original source