【发布时间】:2014-08-27 21:47:44
【问题描述】:
我正在尝试实现一个简单的工具栏。现在我被困在基础上。
我目前的目标:
位于应用侧面的工具栏,允许用户将小部件添加到主 gui。
我目前的进度:
位于正确位置的白色矩形。添加正确小部件的按钮。我需要正确定位按钮。
理想情况下,我想使用某种布局(Box?)。但是我不知道如何将它嵌入到矩形中。
我也不知道为什么我到目前为止所做的一切都不起作用。
当前代码:
我将附上一段工作代码,其中按钮位置不正确。如果这更有帮助,我会很乐意提供最少的代码(请问:))。
Python 代码:
from kivy.app import App
from kivy.uix.widget import Widget
from kivy.uix.button import Button
from kivy.uix.boxlayout import BoxLayout
from kivy.properties import Property, NumericProperty, ReferenceListProperty,\
ObjectProperty
from kivy.graphics import Color, Ellipse, Line
from kivy.clock import Clock
import math
class GraphToolBar(Widget):
def add_buttons(self, game):
createNodeButton = Button(text = 'CreateNode', pos = (self.x,game.height))
createEdgeButton = Button(text = 'CreateEdge', pos = (self.x,0.8*game.height))
self.add_widget(createNodeButton)
self.add_widget(createEdgeButton)
def createNode(instance):
newNode = GraphNode()
game.add_widget(newNode)
print "Node Created"
def createEdge(instance):
newEdge = GraphEdge()
game.add_widget(newEdge)
print "Edge Created"
createNodeButton.bind(on_press=createNode)
createEdgeButton.bind(on_press=createEdge)
pass
class GraphInterface(Widget):
node = ObjectProperty(None)
toolbar = ObjectProperty(None)
def update(self, dt):
for widget in self.children:
if isinstance(widget, GraphEdge) and widget.collide_widget(self):
widget.check_connection()
def construct_toolbar(self):
self.toolbar.add_buttons(self)
class GraphNode(Widget):
r = NumericProperty(1.0)
def __init__(self, **kwargs):
self.size= [50,50]
self.pos = [175,125]
self.r = 1.0
super(GraphNode, self).__init__(**kwargs)
def on_touch_down(self, touch):
if self.collide_point(*touch.pos):
if touch.grab_current == None:
self.r = 0.6
touch.grab(self)
return True
return super(GraphNode, self).on_touch_down(touch)
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):
widget.snap_to_node(self)
def on_touch_up(self, touch):
if touch.grab_current is self:
touch.ungrab(self)
self.r = 1.0
# and finish up here
pass
class GraphEdge(Widget):
r = NumericProperty(1.0)
connected_point_0 = Property(False)
connected_point_1 = Property(False)
connected_node_0 = Widget()
connected_node_1 = Widget()
def __init__(self, **kwargs):
super(GraphEdge, self).__init__(**kwargs)
with self.canvas:
Color(self.r, 1, 1, 1)
self.line = Line(points=[100, 200, 200, 200], width = 2.0, close = True)
self.center = ((self.line.points[0]+self.line.points[2])/2,(self.line.points[1]+self.line.points[3])/2)
def snap_to_node(self, node):
if self.collide_widget(node):
distance_from_0 = [math.sqrt(((self.line.points[0]-node.center[0])**2 + (self.line.points[1]-node.center[1])**2))]*2
distance_from_1 = [math.sqrt(((self.line.points[2]-node.center[0])**2 + (self.line.points[3]-node.center[1])**2))]*2
if distance_from_0 < distance_from_1:
if (self.connected_point_0 is False):
print "collision"
if node is not self.connected_node_1:
self.connected_point_0 = True
self.connected_node_0 = node
self.line.points = node.center + self.line.points[2:]
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)
return True
elif distance_from_1 < distance_from_0:
if (self.connected_point_1 is False):
print "collision"
if node is not self.connected_node_0:
self.connected_point_1 = True
self.connected_node_1 = node
self.line.points = self.line.points[:-2] + 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)
return True
pass
def check_connection(self):
if self.connected_point_0:
self.line.points = self.connected_node_0.center + self.line.points[2:]
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)
self.r = self.connected_node_1.r
if self.connected_point_1:
self.line.points = self.line.points[:2] + self.connected_node_1.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)
self.r = self.connected_node_1.r
class GraphApp(App):
def build(self):
game = GraphInterface()
game.construct_toolbar()
Clock.schedule_interval(game.update, 1.0/20.0)
return game
if __name__ == '__main__':
GraphApp().run()
.kv 文件:
#:kivy 1.0.9
<GraphInterface>:
node: graph_node
toolbar: graph_toolbar
GraphNode:
id: graph_node
center: self.parent.center
GraphToolBar:
id: graph_toolbar
size: root.width * 2/10, root.height
x: root.width * 8/10
y: 0
<GraphToolBar>:
size: 10,100
canvas:
Color:
rgba: (1,1,1,1)
Rectangle:
size: self.size
pos: self.pos
<GraphNode>:
size: 50, 50
canvas:
Color:
rgba: (root.r,1,1,1)
Ellipse:
pos: self.pos
size: self.size
<GraphEdge>:
size: self.size
center: self.center
canvas:
Color:
rgba: (root.r,1,1,1)
Line:
width: 2.0
close: True
感谢您的耐心等待!
【问题讨论】:
标签: android python python-2.7 drawing kivy