Kivy:在我的应用程序中添加工具栏

2024-06-26 17:05:50 发布

您现在位置:Python中文网/ 问答频道 /正文

我试图实现一个简单的工具栏。现在我还停留在基础知识上。在

我目前的目标:

位于应用程序一侧的工具栏,允许用户向主gui添加小部件。在

我目前的进度:

位于正确位置的白色矩形。按钮添加正确的小部件。我需要把按钮放好。在

它看起来像理想的我想使用某种布局(框?)。然而,我不知道如何嵌入这个矩形。在

我也不知道为什么到目前为止我所做的一切都没用。在

当前代码:

我将附加一段代码,其中的按钮没有正确定位。我很乐意提供最小的代码,如果这是更有用的(只要问:)。在

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文件:

^{pr2}$

谢谢你的耐心!在


Tags: fromimportselfgamenodeifdefline
1条回答
网友
1楼 · 发布于 2024-06-26 17:05:50

如果我没听错的话,你只想把那些按钮放在白色的长方形上。如您所述,使用BoxLayout可以很容易地完成这一点。把这条线改一下

class GraphToolBar(Widget):

到这条线

^{pr2}$

相关问题 更多 >