Kivy:在应用的理解控件实例(Kivy: understanding widget instanc

2019-09-25 18:09发布

我仍在升温到这个Kivy东西,希望你不要离开我介意另一个问题!

我想了解我的一些小部件的调度事件。 对于环境的缘故,我希望能够给移动节点到边,并有边缘“捕捉到”的节点。

这里是我的.kv文件:

<GraphInterface>:
    node: graph_node
    edge: graph_edge

    GraphNode:
        id: graph_node
        center: self.parent.center

    GraphEdge:
        id: graph_edge
        center: 200,200

<GraphNode>:
    size: 50, 50
    canvas:
        Color:
        rgba: (root.r,1,1,1)
    Ellipse:
        pos: self.pos
        size: self.size


<GraphEdge>:
    size: self.size
    canvas:
        Color:
            rgba: (root.r,1,1,1)
        Line:
            width: 2.0
            close: True

我有节点和边缘之间的碰撞检测事件,我动态我的程序中创建节点和边缘。 下面是相关Python代码:

class GraphInterface(Widget):
    node = ObjectProperty(None)
    edge = ObjectProperty(None)

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

class GraphEdge(Widget):
    r = NumericProperty(1.0)
    def __init__(self, **kwargs):
        super(GraphEdge, self).__init__(**kwargs)
        with self.canvas:
            self.line = Line(points=[100, 200, 200, 200], width = 2.0, close = True)

    def snap_to_node(self, node):
        if self.collide_widget(node):
            print "collision detected"
            del self.line.points[-2:]
            self.line.points+=node.center
            self.size = [math.sqrt(((self.line.points[0]-self.line.points[2])**2 + (self.line.points[1]-self.line.points[3])**2))]*2
            self.center = ((self.line.points[0]+self.line.points[2])/2,(self.line.points[1]+self.line.points[3])/2)
    pass

class GraphApp(App):

    def build(self):
        node = GraphNode()
        game = GraphInterface()

        createNodeButton = Button(text = 'CreateNode', pos=(100,0))
        createEdgeButton = Button(text = 'CreateEdge')
        game.add_widget(createNodeButton)
        game.add_widget(createEdgeButton)

        #scatter = Scatter(do_rotation=False, do_scale=False)
        #scatter.add_widget(node)

        def createNode(instance):
            newNode = GraphNode()
            game.add_widget(newNode)
            #scatter.add_widget(newNode)
            print "Node Created"

        def createEdge(instance):
            newEdge = GraphEdge()
            game.add_widget(newEdge)
            #scatter.add_widget(newEdge)
            print "Edge Created"

        createNodeButton.bind(on_press=createNode)
        createEdgeButton.bind(on_press=createEdge)

        Clock.schedule_interval(game.update, 1.0/60.0)   
        return game

好了,这是一个很大阅读(对不起)!

基本上我的碰撞只针对最初的边沿和节点我在.kv文件创建检测。 新创建的边和节点无法通过冲突机制进行交互。

我可以把更多的代码,如果人们想要,但我认为这应该是所有的相关部分。 谢谢!

编辑:

新方法:

def on_touch_move(self, touch):
    if touch.grab_current is self:
        self.pos=[touch.x-25,touch.y-25]
    for widget in self.parent.children:
        if isinstance(widget, GraphEdge) and widget.collide_widget(self):
            print "collision detected"
            widget.snap_to_node(self)
            return True
    return super(GraphNode, self).on_touch_move(touch)

有了这个代码,我仍然可以打破依靠快速的移动节点的连接。

EDIT2:

我也许给出了答案过早了一点。 我只能用第一边缘我产生了互动。 我也有一个奇怪的错误,其中第一边缘和第一个节点似乎有相同的颜色属性。 虽然这也许应该在它自己的问题被提出。

Answer 1:

问题是,你不应对新GraphEdge S或GraphNode S是添加到您的GraphInterface 。 在update

    self.edge.snap_to_node(self.node)

self.edge总是KV-创建GraphEdge 。 同样的, self.node

你应该尝试加入这个互动的GraphNode类本身,在您的触摸交互。 尝试在这样的GraphNode.on_touch_move()

for widget in self.parent.children:
    if isinstance(widget, GraphEdge) and widget.collide_widget(self):
        print "collision detected"
        ...
        break

这样,每个GraphNode搜索通过它的兄弟姐妹对任何GraphEdge与它可能发生碰撞。



文章来源: Kivy: understanding widget instances in apps