Kivy:了解应用程序中的小部件实例 [英] Kivy: understanding widget instances in apps

查看:144
本文介绍了Kivy:了解应用程序中的小部件实例的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我仍在为Kivy做准备,希望您不要介意我的另一个问题!

I'm still warming up to this Kivy stuff, hope you don't mind another question from me!

我试图了解我的一些小部件的预定事件.出于上下文考虑,我希望能够将节点移动到边缘,并使边缘捕捉"到该节点.

I'm trying to understand scheduled events for some of my widgets. For the sake of context, I want to be able to move nodes onto edges, and have the edges 'snap to' the node.

这是我的.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代码:

I have a collision detection event between nodes and edges, and I am dynamically creating nodes and edges within my program. Here is the relevant python code:

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

好,所以要阅读很多(对不起)!

Ok, so that's a lot to read (sorry)!

基本上,仅针对在.kv文件中创建的初始边缘和节点检测到我的碰撞.新创建的边缘和节点无法通过碰撞机制进行交互.

Basically my collision is only detected for the initial edges and nodes I create in the .kv file. The newly created edges and nodes cannot interact via the collision mechanism.

如果人们愿意,我可以提供更多代码,但我认为这应该是所有相关的部分.谢谢!

I can put up more code if people want but I think that should be all the relevant parts. Thanks!

新方法:

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)

使用此代码,我仍然可以通过快速移动节点来断开连接.

With this code I can still break the connection by moving the nodes quickly.

我也许还为时过早.我只能与产生的第一个边缘互动.而且我还有一个怪异的错误,其中第一个边缘和第一个节点似乎具有相同的颜色属性.尽管也许应该在它自己的问题中提出这个问题.

I perhaps gave the answer a little prematurely. I can only interact with the first edge I spawned. And I also have a weird bug where the first edge and the first node seem to have the same color properties. Though perhaps this should be posed in it's own question.

推荐答案

问题是您不会对添加到GraphInterface的新GraphEdgeGraphNode做出反应.在update:

The problem is that you don't react to new GraphEdges or GraphNodes being added to your GraphInterface. In update:

    self.edge.snap_to_node(self.node)

self.edge始终是kv创建的GraphEdge.与self.node相同.

self.edge is always the kv-created GraphEdge. Same with self.node.

您应该尝试在触摸交互中将此交互添加到GraphNode类本身中.在GraphNode.on_touch_move()中尝试这样的事情:

You should try adding this interaction to the GraphNode class itself, in your touch interactions. Try something like this in 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.

This way, each GraphNode searches through its siblings for any GraphEdge with which it may collide.

这篇关于Kivy:了解应用程序中的小部件实例的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆