1

我有一个Widget名为KivyMainPage的具有子小部件的名称。EventDispatcher这些子小部件需要访问与其父级相同的消息调度程序(与 Kivy's 无关):

class MainPage(Widget):
    def __init__(self, dispatcher):
        self.child = ChildWidget(dispatcher)
        self.add_widget(child1)

.kv文件中我定义了 的视觉属性<ChildWidget>,但我没有指定它在里面的位置<MainPage>。我想<MainPage>指定它的孩子应该如何定位。这样的事情可能吗?

<ChildWidget>:
    ...

<MainPage>:
    self.child:
        pos: (10, 10)
4

2 回答 2

1

假设 ChildWidget 仍然是 Kivy Widget(继承自Widget或其子类)。

[使用kv的简单方法]

如果你想让孩子控制它在它的父母里面的位置,你可以这样做::

<ChildWidget>
    pos:  (self.parent.x + 10, self.parent.y + 10) if self.parent else (100, 100)

为了控制孩子们的位置,可以这样做:

<MainPage>
    on_children:
        # reposition children
        root.reposition_children(args[1])
    on_size:
        # reposition children when parents size changes
        root.reposition_children(self.children)
    on_pos:
        # reposition children when widgets size changes
        root.reposition_children(self.children)

在你的 .py

class MainPage(Widget):
    ...
    ...
    def reposition_children(self, children):
        for child in children:
            child.pos = x, y
            child.size = d, e

[更详细和完整的方式]

您本质上似乎想要的是您的 Main Widget 表现得像Layout。此链接指向还包括内联文档的代码。代码本身是一个抽象类,它为您提供有关如何构建/设计布局的指南。

您应该从Layout类继承并在 do_layout 中进行小部件定位,通过self.trigger_layout 调用它(这样小部件的定位会延迟到它们需要显示在屏幕上之前,并且触发器确保不调用该函数每帧多次)。

您应该将 trigger_layoutchildren、size、pos...等属性绑定,以便do_layout在这些属性更改时重新触发。

于 2013-07-28T19:04:34.943 回答
1

如果您的定位目标不是太复杂,aRelativeLayout可能就足够了。

class MainPage(RelativeLayout):
    def __init__(self, dispatcher, **kwargs):
        super(MainPage, self).__init__(**kwargs)
        self.child = ChildWidget(dispatcher, pos=(10,10))
        self.add_widget(self.child)

RelativeLayout通常是任何布局 - 除了保持绝对定位的 FloatLayout )保持子级更新到父级的位置。所有的布局也是小部件,所以你应该是安全的。

<ChildWidget>:
    size_hint: .1, .05
    text: "press me"
    on_press: self.parent.pos = (200,200)
<MainPage>:
    pos: 400,400

这是我尝试过的完整代码:

from kivy.app import App
from kivy.lang import Builder
from kivy.uix.relativelayout import RelativeLayout
from kivy.uix.button import Button

Builder.load_string("""
<ChildWidget>:
    size_hint: .1, .05
    text: "press me"
    on_press: self.parent.pos = (200,200)
<MainPage>:
    pos: 400,400
""")

class Dispatcher():
    pass

class ChildWidget(Button):
    def __init__(self, dispatcher, **kwargs):
        super(ChildWidget, self).__init__(**kwargs)
        self.dispatcher = dispatcher

class MainPage(RelativeLayout):
    def __init__(self, dispatcher, **kwargs):
        super(MainPage, self).__init__(**kwargs)
        self.child = ChildWidget(dispatcher, pos=(10,10))
        self.add_widget(self.child)

class TestApp(App):
    def build(self):
        dispatcher = Widget()
        return MainPage(dispatcher)

if __name__ == '__main__':
    TestApp().run()
于 2013-07-29T02:58:31.840 回答