collide_widget负面大小

时间:2016-04-02 21:58:23

标签: python kivy

我有一些小工具,想要拖动并选择"他们。我使用选择小部件作为矩形来显示选择大小,然后使用for child in root.children: selection.collide_widget(child)。只要我从左下方向右上方向拖动,这就行得很好,因为选择窗口小部件的大小将为正。

预计具有负尺寸的小部件不能与collide_widget一起使用吗?

我根本不应该为小部件使用负片尺寸吗?

kv文件:

<SelectionBox>:
    size: 0,0
    size_hint: None, None
    canvas:
        Color:
            rgba: 1, 1, 1, 0.1
        Rectangle:
            pos: root.pos
            size: root.size

<Selectable>:
    size: 32, 32
    size_hint: None, None
    canvas:
        Color:
            rgba: 0, 1, 0, 1
        Rectangle:
            pos: root.pos
            size: root.size

代码:

class Selectable(Widget):
    pass

class Canvas(FloatLayout):

    touch_down = False

    def on_touch_down(self, touch):
        self.selection = sel = SelectionBox()
        sel.pos = touch.pos
    self.touch_down = True
        self.add_widget(sel)

    def on_touch_move(self, touch):
        if self.touch_down:
#~~~~~~~~~~~~~~~~~~~~~~~~~ Interesting line here ~~~~~~~~~~~~~~~~~~~~~~~~~
            # size can get negative 
            self.selection.size = (touch.pos[0] - self.selection.pos[0] , touch.pos[1] - self.selection.pos[1])

    def on_touch_up(self, touch):

        for widget in self.children:
            if widget is self.selection:
                print("Children is selection")
            if self.selection.collide_widget(widget):
            print("Widget collides: {}".format(widget))

        self.touch_down = False
        self.remove_widget(self.selection)

canvas = Canvas()

class MyApp(App):
    def build(self):
        canvas = Canvas()
    for i in range(0,11):
        sel = Selectable()
        sel.pos = random.random() * 1000, random.random() * 1000
        self.add_widget(sel)
        return canvas

if __name__ == "__main__":
    MyApp().run()

1 个答案:

答案 0 :(得分:1)

确实,这种行为是预料之中的。来自def collide_widget(self, wid): if self.right < wid.x: return False if self.x > wid.right: return False if self.top < wid.y: return False if self.y > wid.top: return False return True

self.right < self.x

对于负尺寸,此逻辑不起作用,例如collide_widget。一个简单的解决方法是重新定义def collide_widget(self, wid): if max(self.x, self.right) < min(wid.x, wid.right): return False if min(self.x, self.right) > max(wid.x, wid.right): return False if max(self.top, self.y) < min(wid.y, wid.top): return False if min(self.top, self.y) > max(wid.y, wid.top): return False return True 这些预期负数大小的类:

collide_widget

这会照顾两个小部件(一个叫Widget和一个正在测试的小部件)有正面或负面的尺寸。

但是,我不确定其他地方的代码是否依赖于负面尺寸而不是按预期发生碰撞(所以猴子补丁要谨慎到BitmapDrawable drawable = (BitmapDrawable) imageView.getDrawable(); Bitmap bitmap = drawable.getBitmap(); )。