Я пытаюсь реализовать простую панель инструментов. Прямо сейчас я застрял на основах.Kivy: добавление панели инструментов в мое приложение
Моя цель:
панель инструментов, которая сидит на стороне приложения, а также позволяет пользователю добавлять виджеты в основной графический интерфейс.
Мой текущий прогресс:
белый прямоугольник, который находится в правильном месте. Кнопки, которые добавляют правильные виджеты. Мне нужно правильно расположить кнопки.
Похоже, что я хотел бы использовать какой-то макет (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
Спасибо за ваше терпение!
Я не понимал, что это будет так просто! Однако, что, если я не хочу полностью заполнять пространство макета кнопками? (Как сейчас, кнопки действительно большие). Я дам вам ответ, так как вы действительно решили проблему. :) – user124784
Когда вы создаете эти кнопки, вы можете использовать 'size_hint' для установки относительного размера или если вы установите его на' (None, None) ', вы можете затем используйте 'size', который устанавливает абсолютный размер. – Tatarkow