2013-07-28 68 views
1

我有一個叫做MainPage的Kivy Widget,它有一個子部件。這些子部件需要訪問相同的消息分派器(有無關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) 

回答

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 

[更詳細和完整的方式]

你什麼本質上似乎想是你的主要的Widget表現得像一個Layout。此鏈接是代碼,其中還包括內聯文檔。代碼本身是一個抽象類,它爲您提供了關於如何構造/構建佈局的指導。

您應該從Layout類繼承,做你的小部件定位於do_layout,把它通過self.trigger_layout(這樣的小部件的定位推遲到他們需要在屏幕上,並觸發顯示之前可確保函數不會每幀調用多次)。

您應該bind trigger_layout與屬性像children, size, pos...,以便do_layout重新觸發,只要這些屬性更改。

1

如果您的定位目標不太複雜,那麼RelativeLayout就足夠了。

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() 
相關問題