在另一个小部件包含的小部件中绘制

drawing in a widget contained by another widget

我正在尝试了解 kv 文件的工作原理。 到目前为止,我已经能够解决几个错误,但我仍然遇到一些不会产生错误但不会产生预期结果的问题。

预期: 我的目标是创建一个包含子小部件的两个实例的父小部件。子小部件包含一个矩形和一个触摸移动指令。我希望每个实例只覆盖主要小部件的一部分(矩形在这里让我看到子小部件在哪里)。我假设触摸移动指令应该只在子窗口部件实例所在的屏幕部分触发。

实际: 子窗口小部件矩形不显示,触摸移动行为在任何地方被触发两次(这让人认为两个子窗口小部件都跨越整个屏幕,但矩形未显示)。 删除父窗口小部件 canvas 不能解决我的问题,仅添加一个子窗口小部件也不能。

我做错了什么?

python 文件:

from kivy.app import App
from kivy.uix.widget import Widget
from kivy.graphics import Rectangle

class MainWidget(Widget):
    pass

class SubWidget(Widget):
    def on_touch_move(self, touch):
        self.center_x, self.center_y = (touch.x, touch.y)
        print touch.x, touch.y

class testApp(App):
    def build(self):
        x = MainWidget()
        return x

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

kv 文件:

#:kivy 1.8.0

<MainWidget>:
    canvas:
        Color:
            rgb: 0,1,0
        Rectangle:
            pos: self.center
            size: 10,10
    SubWidget:
        pos: self.width - self.width/5 ,0
        size: self.width/5 , self.height
    SubWidget:
        pos: 0, 0
        size: self.width/5 , self.height

<SubWidget>:
    canvas:
        Color:
            rgb: 1,0,0
        Rectangle:
            pos: self.pos
            size: self.size

提前感谢您的回答。

编辑: 1) 应在布局中添加子部件。还是需要想办法 在布局中正确定位我的小部件。 2)即使没有直接点击小部件,也会触发小部件的触摸事件。使用 widget.collide_point(*touch.pos) 使其工作。

编辑2: 修复了 .kv。 Self.parent.pos/size 表现不一致,所以我转到了 root。pos/size :

#:kivy 1.8.0

<MainWidget>:
    canvas:
        Color:
            rgb: 0,1,0
        Rectangle:
            pos: self.center
            size: 10,10
    FloatLayout:
        SubWidget:
            pos: root.width - root.width/5 ,0
            size: root.width/5 , root.height
        SubWidget:
            pos: 0, 0
            size: root.width/5 , root.height

<SubWidget>:
    canvas:
        Color:
            rgb: 1,0,0
        Rectangle:
            pos: self.pos
            size: self.size

我认为您需要将子元素放入 box layout。 所以它会是这样的。

<MainWidget>:
    canvas:
        ...
    BoxLayout:
        SubWidget:
            ...
        SubWidget:
            ...

SubWidget 元素的属性(如 pos)可能需要一些更改。

还有更多信息 here

I assume the on-touch-move instructions should trigger only on the part of the screen where the sub-widget instance is.

这个假设是不正确的。要自己检查碰撞,您可以在 on_touch_move 方法中执行 if self.collide_point(*touch.pos): ...

此外,您的定位问题是由于仅使用小部件引起的 - 这些小部件不会对其子部件施加任何影响,因此除根小部件之外的所有部件都具有默认位置 (0, 0) 和大小 (100, 100) .您应该使用布局 类 让小部件自动调整其子项的大小和位置。