Skip to main content
 首页 » 编程设计

python之应用 pos_hint 后获取小部件 XY 位置

2025年05月04日8bjzhanghao

使用 pos_hint 定位小部件(例如 Scatter)后,如何获取当前的 x、y 位置 (pos)?

例如

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. 


编辑:示例代码

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() 

请您参考如下方法:

问题是窗口(和布局本身)在分配布局支持的值(如 size_hint 或 pos_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()