0
我试图实现一个简单的工具栏。现在我被困在基础知识上。Kivy:将工具栏添加到我的应用程序
我现在的目标是:
它坐落在应用的边,并允许用户以小部件添加到主界面的工具栏。
我目前的进度:
一个白色矩形,在正确的位置坐下。添加正确小部件的按钮。我需要正确定位按钮。
它看起来像理想情况下我想使用某种布局(盒?)。但是我无法弄清楚如何在矩形上嵌入它。
我也不知道为什么我迄今为止所做的都不起作用。
目前代码:
我会附上的代码,该按钮的位置不正确工作件。如果这更有帮助,我会很乐意提供最少的代码(只要问:))。
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
感谢您的耐心!
我没想到它会这么简单!但是,如果我不想用按钮完全填充布局空间呢? (因为现在按钮非常大)。我会给你答案,因为你已经解决了我的问题:) – user124784 2014-08-28 12:57:50
当你创建这些按钮,你可以使用'size_hint'来设置相对大小,或者如果你把它设置为'(None,None)',你可以然后使用'size',它设置绝对大小。 – Tatarkow 2014-08-28 13:47:32