在Kivy中使用和移动WidgetsButtons。

问题描述 投票:2回答:2

我刚刚开始使用Kivy,和我习惯的不一样,如果我犯了愚蠢的错误,请原谅!

现在,我正试图创建一个应用程序,它可以实现以下功能。

  • 允许创建节点(目前是省略号) Allows creation of Nodes (ellipses for now).
  • 允许用户通过拖动来定位节点。
  • 允许用户用线连接节点。

到目前为止,我已经实现了第一条,第二条也有点实现了。

现在我的拖动效果不是很好。如果我移动鼠标太快,它就会取消移动方法(因为它不再接触)。有没有更好的方法来产生拖动,或者我只需要增加刷新率(如果有,怎么做?

def on_touch_move(self, touch):
   if self.collide_point(touch.x, touch.y):
       self.pos=[touch.x-25, touch.y-25]

我试过用Buttons代替,用on_press方法更好地跟踪移动。然而现在我在更新按钮的位置时遇到了困难(主要是语法问题)。

    class GraphNode(Button):
       background_disabled_down=1
       background_disabled_normal=1

       def moveNode(self):
           with touch:
               self.pos=[touch.x-25, touch.y-25]

我不知道如何使用触摸值,一直得到一个错误数组。(显然目前的尝试并不成功,我只是觉得很有趣)。

你可能也知道,我也不知道如何摆脱按钮图形,因为我想使用椭圆。作为额外的奖励,如果有人能告诉我如何改变按钮上椭圆的颜色,那将是很酷的。

kv文件。

    <GraphNode>:
        size: 50, 50
        canvas:
            Ellipse:
                pos: self.pos
               size: self.size
        on_press:
            root.moveNode()

我想利用触摸信息来更新位置 但不知道如何在这里实现。

完整的python核心代码。

    from kivy.app import App
    from kivy.uix.widget import Widget
    from kivy.uix.button import Button
    from kivy.properties import NumericProperty, ReferenceListProperty,\
        ObjectProperty
    from kivy.graphics import Color, Ellipse, Line


    class GraphInterface(Widget):
        node = ObjectProperty(None)



    class GraphApp(App):

        def build(self):
            node = GraphNode()
            game = GraphInterface()

            createNodeButton = Button(text = 'CreateNode', pos=(100,0))
            createEdgeButton = Button(text = 'CreateEdge')
            game.add_widget(createNodeButton)
            game.add_widget(createEdgeButton)

            def createNode(instance):
                game.add_widget(GraphNode())
                print "Node Created"

            def createEdge(instance):
                game.add_widget(GraphEdge())
                print "Edge Created"

            createNodeButton.bind(on_press=createNode)
            createEdgeButton.bind(on_press=createEdge)
            return game

    class GraphNode(Button):

        def moveNode(self):
            with touch:
                self.pos=[touch.x-25, touch.y-25]


       #def onTouchMove(self, touch):
       #   if self.collide_point(touch.x, touch.y):
       #       self.pos=[touch.x-25, touch.y-25]
        pass

    class GraphEdge(Widget):

        def __init__(self, **kwargs):
            super(GraphEdge, self).__init__(**kwargs)
            with self.canvas:
                Line(points=[100, 100, 200, 100, 100, 200], width=1)
        pass

    if __name__ == '__main__':

        GraphApp().run()

如果你需要其他信息,或者有什么不清楚的地方,请告诉我!

编辑:第二个问题移至。在Kivy中创建动态绘制的线条.

python python-2.7 drawing kivy
2个回答
5
投票

首先,你应该阅读一下 触摸事件 在Kivy中。这里特别值得关注的是关于抓取触摸事件的部分。基本上,你可以 "抓取 "一个触摸,以确保抓取的部件总是能从该触摸中接收到进一步的事件--换句话说就是 on_touch_moveon_touch_up 后的触摸事件将被发送到您的小组件。

基本的例子。

class MyWidget(Widget):
    def on_touch_down(self, touch):
        if self.collide_point(*touch.pos):
            touch.grab(self)
            # do whatever else here

    def on_touch_move(self, touch):
        if touch.grab_current is self:
            # now we only handle moves which we have grabbed

    def on_touch_up(self, touch):
        if touch.grab_current is self:
            touch.ungrab(self)
            # and finish up here

但是,甚至更好!如果你想在周围拖动widget,Kivy已经有了这个功能。Scatter.

只要将你的widget包裹在一个 Scatter 你可以拖动它。你也可以使用多点触控来旋转和缩放一个对象。Scatter但你可以很容易地禁用它(kv)。

FloatLayout:
    Scatter:
        do_scale: False
        do_rotation: False

        MyWidget:

侧面说明 - 这是不正确的。

class GraphNode(Button):
   background_disabled_down=1
   background_disabled_normal=1

background_disabled_downbackground_disabled_normalKivy属性 - 你应该把这些值设置在 __init__.

强制执行这些数值。

class GraphNode(Button):
    def __init__(self, **kwargs):
        super(GraphNode, self).__init__(background_disabled_down='',
                                        background_disabled_normal='', **kwargs)

建议这些值(更好的选择)。

class GraphNode(Button):
    def __init__(self, **kwargs):
        kwargs.setdefault('background_disabled_down', '')
        kwargs.setdefault('background_disabled_normal', '')
        super(GraphNode, self).__init__(**kwargs)

最后,请注意,这些属性是 指向残障人士使用的图像的文件名。Button. 如果你删除这些值,并禁用你的按钮,它将不会绘制任何背景。

© www.soinside.com 2019 - 2024. All rights reserved.