user124784 user124784 - 28 days ago 9
Python Question

Creating a dynamically drawn line in Kivy

This is a continuation of my post here: Using and moving Widgets/Buttons in Kivy

I want to create a line between two nodes(ellipses) in Kivy, so that the end points can be dynamically updated as I move the nodes. Here is my current messy framework:

class GraphEdge(Widget):

def __init__(self, **kwargs):
super(GraphEdge, self).__init__(**kwargs)
with self.canvas:
Line(points=[100, 100, 200, 100, 100, 200], width=1)
pass


I've just put in some placeholder value for the points, as I'm not sure how to even start using the values from the other widgets within the App.

My end goal is to be able to select two nodes and click a button to add the line (or something even cleaner). I'm not asking someone to produce this for me, just some pointers in the right direction would be awesome :).

More info is available in the linked post, but I'm happy to put more here if requested.

Thanks.

Edit:

Additional info:

I want to update the position of the line based on some event. For example if I move an ellipse onto the line, I want the closest edge to snap to the ellipse and follow it.

def snap_to_node(self, node):
if self.collide_widget(node):
print "collision detected"
self.line.points=[node.pos]


(This is just a poor attempt, I know it doesn't work at all)
The end goal is to be able to connect 'nodes' with 'edges'.

Edit2:

So I've made some progress. I created an update method which is called in the clock schedule:

def update(self, dt):
# detect node collision
self.edge.snap_to_node(self.node)


def snap_to_node(self, node):
if self.collide_widget(node):
print "collision detected"
self.line.points+=node.pos


Now I want to make it so that I only update one of the point sets (the idea is that I snap one of the line ends to the node).

So far this code only detects collections on one of the points of the line. And the additional points don't detect collisions.

Answer
Line(points=[100, 100, 200, 100, 100, 200], width=1)

^^ you can replace this with

self.line = Line(points=[100, 100, 200, 100, 100, 200], width=1)

Then later simply modify the line by doing things like self.line.width = 2 or self.line.points = [200, 100, 100, 200, 200, 100].

Other than that, I'm not sure what you're asking, could you be more specific?