1

子ウィジェットを持つKivyWidgetという名前があります。これらの子ウィジェットは、親MainPageと同じメッセージ ディスパッチャー (Kivy とは関係ありません) にアクセスできる必要があります。EventDispatcher

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

ポジショニングの目標がそれほど複雑でない場合は、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 に答える
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_layoutをchildren、size、posなどのプロパティとバインドする必要があります。do_layout

于 2013-07-28T19:04:34.943 に答える