在 Kivy 中使用和移动小部件/按钮 [英] Using and moving Widgets/Buttons in Kivy

查看:24
本文介绍了在 Kivy 中使用和移动小部件/按钮的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我刚开始使用 Kivy,它与我习惯的不同,如果我犯了愚蠢的错误,请道歉!

I'm just starting off with Kivy and it's different to what I'm used to, apologies if I'm making stupid mistakes!

现在我正在尝试创建一个执行以下操作的应用:

Right now I'm trying to create an app that does the following:

  • 允许创建节点(现在是省略号).
  • 允许用户通过拖动来定位节点.
  • 允许用户用线连接节点.

到目前为止,我已经实现了第一个,并且在某种程度上实现了第二个.

So far I've achieved the first, and the second somewhat.

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

Right now my dragging is not working too well. If I move the mouse too quickly it cancels the move method (as it is no longer in contact). Is there a better way to produce dragging or do I just increase the refresh rate (if so how?).

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 方法更好地跟踪移动.但是现在我很难更新按钮的位置(主要是语法).

I've tried using Buttons instead, using the on_press method to track the moving better. However now I'm having difficulty updating the position of the button (mostly just syntax).

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

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

我不知道如何使用触摸值,并不断收到一系列错误.(显然目前的尝试是行不通的,我只是觉得很好笑).

I have no idea how to use the touch value, and keep getting an array of errors. (Obviously the current attempt doesn't work, I just thought it was funny).

您可能会说,我也不知道如何摆脱按钮图形,因为我想使用椭圆.如果有人可以告诉我如何在按下按钮时更改椭圆的颜色,那将是一个额外的奖励!

As you could probably tell, I also don't know how to get rid of the button graphics, as I want to use the ellipse. As an added bonus if someone could show me how to change the colour of the ellipse on button press that would be cool!

kv 文件:

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

我希望能够使用触摸信息来更新位置,但这里不知道如何实现.

I want to be able to use the touch information to update the position, but don't know how to implement it here.

完整的核心python代码:

Full core python code:

    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()

如果您需要任何其他信息,或者有任何不清楚的地方,请告诉我!

If you need any other info, or anything is unclear, please let me know!

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

推荐答案

首先,你应该阅读 触摸事件.这里特别感兴趣的是关于抓取触摸事件的部分.基本上,您可以抓取"一个触摸以确保抓取小部件将始终从该触摸接收更多事件 - 换句话说,该触摸事件之后的 on_touch_moveon_touch_up将发送到您的小部件.

First, you should read up on touch events in Kivy. Of particular interest here is the section on grabbing touch events. Basically, you can "grab" a touch to ensure that the grabbing widget will always receive further events from that touch - in other words, the on_touch_move and on_touch_up following that touch event will be sent to your widget.

基本示例:

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

但是,更好!如果您希望能够拖动小部件,Kivy 已经有了:分散.

But, even better! If you want to be able to drag widgets around, Kivy already has that: Scatter.

只需将您的小部件包装在 Scatter 中,您就可以拖动它.您还可以使用多点触控来旋转和缩放 Scatter,但您可以轻松禁用它 (kv):

Just wrap your widget in a Scatter and you can drag it around. You can also use multitouch to rotate and scale a Scatter, but you can easily disable that (kv):

FloatLayout:
    Scatter:
        do_scale: False
        do_rotation: False

        MyWidget:


旁注 - 这是不正确的:


Side note - this is incorrect:

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

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

background_disabled_down and background_disabled_normal are Kivy properties - you should set those values in __init__.

强制这些值:

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

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

Suggest these values (better option):

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

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

Finally, note that these properties are filenames pointing to the images used for the disabled Button. If you remove these values, and disable your button, it will draw no background whatsoever.

这篇关于在 Kivy 中使用和移动小部件/按钮的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆