Reputation: 117
After positioning a widget (e.g. Scatter) using pos_hint, how do I get the current x, y position (pos) ?
e.g.
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: example code
from kivy.app import App
from kivy.lang import Builder
from kivy.uix.scatter import Scatter
Builder.load_string("""
<Icon@Scatter>:
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()
Upvotes: 2
Views: 2383
Reputation: 19027
The problem is that the Window (and the layout itself) is not refresh immediately after assigning values that are honoured by layouts (like size_hint
or pos_hint
). They are updated just after the window is refresh (until the method ends)
You basically can call the method do_layout
explicitly. The documentation said that "this method is called when a layout is needed, by a trigger". I have to say that I am not sure if calling it explicitly could cause some problems because this kind of use is not documented. It is working for me but be careful:
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
This is not necessary when you let the window refresh, i.e. after you can actually see that the Scatter
(or any other Widget
) has moved.
EDIT: corrected version of the code in the question
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()
Upvotes: 1