2014-08-27 53 views
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 

感谢您的耐心!

回答

1

如果我正确理解你,你只是想把这些按钮放到白色的矩形上。正如你所提到的,这可以通过使用BoxLayout轻松完成。只是改变这一行

class GraphToolBar(Widget): 

这一行

class GraphToolBar(BoxLayout): 
+0

我没想到它会这么简单!但是,如果我不想用按钮完全填充布局空间呢? (因为现在按钮非常大)。我会给你答案,因为你已经解决了我的问题:) – user124784 2014-08-28 12:57:50

+1

当你创建这些按钮,你可以使用'size_hint'来设置相对大小,或者如果你把它设置为'(None,None)',你可以然后使用'size',它设置绝对大小。 – Tatarkow 2014-08-28 13:47:32

相关问题