我还在为 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)
使用此代码,我仍然可以通过快速移动节点来断开连接。
编辑2:
也许我给出的答案有点过早了。我只能与我生成的第一个边缘进行交互。我还有一个奇怪的错误,其中第一个边缘和第一个节点似乎具有相同的颜色属性。尽管也许这应该在它自己的问题中提出。
最佳答案
问题是您对添加到 GraphInterface
中的新 GraphEdge
或 GraphNode
没有反应。在更新
中:
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
。
关于python - Kivy:理解应用程序中的小部件实例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25317612/