2013-08-04 30 views
2

使用pos_hint定位控件(例如Scatter)後,如何獲取當前的x,y位置(pos)?在應用pos_hint後獲取控件的XY位置

例如

wid.pos = (250, 350) 
print wid.pos <----- # it print (200, 350). Correct. 
wid.pos_hint = {'top':0.9, 'right':0.5} # moved the widget to other position using pos_hint. 
print wid.pos <----- # it sill print (200, 350) eventhough the widget position has changed. 


EDIT:例如代碼

from kivy.app import App 
from kivy.lang import Builder 
from kivy.uix.scatter import Scatter 

Builder.load_string(""" 
<[email protected]>: 
    size_hint: .06, .08 

    Image: 
     size: root.size 
     allow_stretch: True 
     keep_ratio: True 
""") 

class Icon(Scatter): 
    def __init__(self, **kwargs): 
     self.pos = (200, 200) 
     self.move() 
     super(Icon, self).__init__(**kwargs) 

    def move(self): 
     print "BEFORE: " 
     print self.pos  # print 200, 200 
     self.pos_hint = {'top':0.9, 'right':0.5} # assume now Scatter has moved to x800 y500. 
     print "AFTER: " 
     print self.pos  # it still print 200, 200 :(


class GameApp(App): 
    def build(self): 
     return Icon() 

if __name__ == '__main__': 
    GameApp().run() 
+0

你似乎在做正確。你期待什麼樣的價值觀?考慮到當你使用'top'和'right'屬性時,Kivy將會使用'Scatter'的父項和** Scatter本身的''top'和'right'邊界** 。您可能期望您將定位分配給左下角,而您實際上是通過使用「頂」和「右」分配到右上角。 –

+0

另外,根據我剛纔所說的,根據父母的情況,「大小」屬性非常重要。如果父類是一個簡單的'Widget','size'將會是100x100(默認),並且,例如,如果是FloatLayout,它可以與父類的尺寸相同(因爲默認值是'size_hint:1 ,1'),所以返回的定位將是'(0,0)'(在這種情況下不完全確定,甚至可能是負值) –

+0

@toto_tico我之前的問題目前還不清楚。我編輯了代碼。在代碼的第3行中,我使用pos_hint移動了小部件(假設新小部件的位置現在爲x500 y600)。因此,在第4行,我實際上期待它打印位置(500,600),但它打印(250,350)。 – oneace

回答

1

的問題是,所述窗口(和佈局本身)未分配由佈局兌現值之後立即刷新(如size_hintpos_hint)。它們在窗口刷新後立即更新(直到方法結束)

您基本上可以明確調用方法do_layout。該文件說,「當需要佈局時,通過觸發器調用此方法」。我不得不說,如果明確地調用它可能會導致一些問題,因爲這種用法沒有記錄。這是爲我工作,但要小心:

wid.pos = (250, 350) 
print wid.pos # it prints (200, 350). Correct. 
wid.pos_hint = {'top':0.9, 'right':0.5} 
print wid.pos # it sill print (200, 350) 
wid.do_layout() 
print wid.pos # it should work now 

當你讓窗口刷新之後,即實際上你可以看到Scatter(或任何其他Widget)移動這是沒有必要的。


編輯:在問題糾正的代碼版本

from kivy.app import App 
from kivy.lang import Builder 
from kivy.uix.scatter import Scatter 
from kivy.uix.floatlayout import FloatLayout 

Builder.load_string(""" 
<Icon>: 
    size_hint: .06, .08 

    Image: 
     size: root.size 
     allow_stretch: True 
     keep_ratio: True 

<BaseLayout>: 
    icon: _icon 
    Icon: 
     id: _icon 
    Button: 
     text: "Press me" 
     size_hint: .1,.05 
     on_press: _icon.move() 
""") 

class Icon(Scatter): 
    def __init__(self, **kwargs): 
     self.pos = (200, 200) 
     super(Icon, self).__init__(**kwargs) 

    def move(self): 
     print "BEFORE: " 
     print self.pos  # print 200, 200 
     self.pos_hint = {'top':0.9, 'right':0.5} # assume now Scatter has moved to x800 y500. 
     self.parent.do_layout() 
     print "AFTER: " 
     print self.pos  # it still print 200, 200 :(


class BaseLayout(FloatLayout): 
    pass 


class GameApp(App): 
    def build(self): 
     return BaseLayout() 

if __name__ == '__m 
ain__': 
    GameApp().run() 
+0

試過了do_layout()方法,結果是一樣的。仍然無法獲得新的職位。 – oneace

+0

還嘗試將代碼(wid.pos_hint = ...)作爲新函數並調用它,但小部件位置仍未更新。 – oneace

+0

我添加了適用於我的代碼。如果代碼適用於您,它可能與您正在操作的上下文有關(例如分散的父項)? –