【问题标题】:Draggable Image in KivyKivy 中的可拖动图像
【发布时间】:2020-12-16 10:13:57
【问题描述】:

所以我一般来说是 Kivy 和 Gui 编码的新手......我正在尝试制作一个可移动的图像,这是我迄今为止尝试过的代码:

from kivy.app import App
from kivy.uix.widget import Widget
from kivy.uix.image import Image
from kivy.uix.behaviors import DragBehavior
from kivy.uix.floatlayout import FloatLayout 

class Box_layout(FloatLayout):
    def __init__(self,**kwargs):
        super(Box_layout, self).__init__(**kwargs)
        self.size_hint = (.50,.50)
        self.orientation = "vertical"
        self.add_widget(MoveableImage())#drag_rectangle = [self.x, self.y, self.width, self.height],source="temp_plot.png"))


class MoveableImage(DragBehavior,Image):

    def __init__(self, **kwargs):
        super(MoveableImage, self).__init__(**kwargs)
        self.drag_timeout = 10000000
        self.drag_distance = 0
        #self.drag = DragBehavior()
        #self.drag.drag_rectangle = [self.x, self.y, self.width, self.height]

        
class gameApp(App):
    def build(self):
        wimg = MoveableImage(source="temp_plot.png")
        m = Box_layout()



if __name__ == '__main__':
    gameApp().run()

发生的情况是我目前有一个空白的“图像”,在第一次单击时可以拖动,但随后达到超时或在移动一次后无法移动的情况.....我认为这是一个超时问题或self.drag_timeout = 10000000 没有解决问题...我在这里做错了什么? 此外,当我将实际来源传递给 MoveableImage 时,即self.add_widget(MoveableImage(source='tmp.png')),图像从一开始就无法移动,这再次让我感到非常困惑....如果有人可以帮助并解释发生了什么然后解释为什么会出现这些行为,这太棒了!

【问题讨论】:

    标签: python kivy


    【解决方案1】:

    您还需要更新MoveableImagedrag_rectangle。最简单的方法是使用kv 语言。所以你的MoveableImage 类可以很简单:

    class MoveableImage(DragBehavior, Image):
        pass
    

    然后像这样加载kv 规则:

    kv = '''
    <MoveableImage>:
        # Define the properties for the MoveableImage
        drag_rectangle: self.x, self.y, self.width, self.height
        drag_timeout: 10000000
        drag_distance: 0
    '''
    Builder.load_string(kv)
    

    在这里使用kv 的好处是它会自动设置绑定,否则您必须自己编写代码。 drag_rectangle 就是一个例子,所以当MoveableImage 被移动(拖动)时,drag_rectangle 会自动更新。

    如果您想自己设置这些绑定(而不是使用kv),您可以将您的MoveableImage 定义为:

    class MoveableImage(DragBehavior, Image):
    
        def __init__(self, **kwargs):
            super(MoveableImage, self).__init__(**kwargs)
            self.drag_timeout = 10000000
            self.drag_distance = 0
            self.drag_rectangle = [self.x, self.y, self.width, self.height]
    
        def on_pos(self, *args):
            self.drag_rectangle = [self.x, self.y, self.width, self.height]
    
        def on_size(self, *args):
            self.drag_rectangle = [self.x, self.y, self.width, self.height]
    

    【讨论】:

    • 谢谢你....我看到过类似的事情,特别是在 Kivy 文档中....虽然是为了实际学习所有 Kivy 类的交互,如果你可以展示如何以“正常”编程方式完成此操作,这对我的理解很有帮助...
    • 我也不明白,我想我尝试了一个与你在那里写的等价的东西,关于维护drag_rectangle,这个'self.drag.drag_rectangle = [self.x, self .y, self.width, self.height]'....这也没有达到我想要的效果...你知道这是为什么吗?抱歉这些简单的问题
    • 我原来的答案是 python/kivy 的“正常”编程方式。但我已经更新了我的答案,以展示如何在没有kv 的情况下做到这一点。请注意,__init__() 方法中的self.drag_rectangle = [self.x, self.y, self.width, self.height] 在执行__init__() 方法时根据MovebleImage 的大小和位置设置drag_rectangle,但此时大小为[100,100],位置为@ 987654344@(默认值)。而__init__() 中的那一行没有设置任何绑定,所以drag_rectangle 的那些值不会被调整。
    • 感谢您的澄清...虽然我猜我的困惑来自您提到的“绑定”...。什么是调用这些函数 on_pos 和 on_size,或者以其他方式触发它们执行?
    • 只要property 发生变化,所有Widgets 的基类EventDispatcher 都会自动调用类的任何on_property() 方法。请参阅Properties Documentation。另一种方法是使用bind,如Widget Documentation中所述。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-01-05
    • 1970-01-01
    • 2013-01-11
    • 1970-01-01
    • 1970-01-01
    • 2016-09-28
    • 2013-02-16
    相关资源
    最近更新 更多