You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Kivy组件位置不稳定:新增组件后布局偏移问题求助

Kivy布局异常问题解决方案

问题核心原因

你用了BoxLayout(orientation='vertical')作为主容器,但给子组件设置了pos_hint——BoxLayout会自动按垂直/水平方向排列子组件,pos_hint在这种布局下完全不生效,这就是所有异常的根源:

  1. 添加lbl_box后它出现在屏幕中部:因为BoxLayout默认会把所有子组件按比例分配空间,你给两个BoxLayout都设了size_hint=(0.4,0.2),剩下的60%垂直空间是空的,所以视觉上lbl_box在中间。
  2. 点击按钮添加GridLayout后lbl_box被上推:因为BoxLayout会重新分配所有子组件的空间,三个组件的size_hint_y加起来是0.2+0.2+0.6=1,刚好填满垂直空间,所以lbl_box会紧贴inp_box。

修复方案

把主布局改成FloatLayout,这样pos_hint和size_hint才能正常生效,让组件按你的预期定位:

import kivy
from kivy.app import App
from kivy.uix.label import Label
from kivy.uix.textinput import TextInput
from kivy.uix.button import Button
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.floatlayout import FloatLayout
from kivy.uix.gridlayout import GridLayout

class MainApp(App):
    def build(self):
        # 替换主布局为FloatLayout
        self.main = FloatLayout()
        self.my_number = '100000'
        inp_box = BoxLayout(pos_hint={'x': 0, 'top': 1},
                            size_hint=(0.4, 0.2))
        inp_box.add_widget(Label(text='Enter something', 
                        size_hint=(None, None),
                        size=(300,50),
                        font_size=25))
        self.get_inp = TextInput(text=self.my_number, 
                        multiline=False, 
                        size_hint=(None, None),
                        size=(125,50),
                        font_size=25)
        go = Button(text='Button',
                    size_hint=(None, None),
                    size=(100,50),
                    font_size=25)
        go.bind(on_release=self.more_widgets)
        inp_box.add_widget(self.get_inp)
        inp_box.add_widget(go)
        self.main.add_widget(inp_box)
        
        # 调整lbl_box的top位置,紧贴inp_box
        lbl_box = BoxLayout(pos_hint={'x': 0, 'top': 0.8},
                            size_hint=(0.4, 0.2))
        for i in ['One', 'Two', 'Three']:
            lbl_box.add_widget(Label(text=i, 
                            size_hint=(None, None),
                            size=(100,50),
                            font_size=20))
        self.main.add_widget(lbl_box)
        
        return self.main
    
    def more_widgets(self, instance):
        self.my_number = self.get_inp.text      
        number_disp = GridLayout(cols=4,
                            pos_hint={'x': 0.1, 'top': 0.5},
                            size_hint=(0.8, 0.6))
        for t in range(0, 20):
            n = int(self.my_number) + t
            number_disp.add_widget(
                        Label(text=f'{t}: {n:,.0f}'))
        self.main.add_widget(number_disp)

if __name__ == '__main__':
    app = MainApp()
    app.run()

关键修改点

  • 主布局替换为FloatLayout:这是支持自由定位的布局,pos_hint和size_hint能正常工作。
  • 移除子组件内部的pos_hint:比如inp_box里的Label、TextInput、Button,它们的父布局是BoxLayout,内部组件的pos_hint无效,直接用固定尺寸即可。
  • 调整lbl_box的pos_hint={'top':0.8}:因为inp_box的size_hint_y=0.2,从顶部往下占了20%高度,设为0.8才能紧贴inp_box。

内容的提问来源于stack exchange,提问作者Tom

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.06 06:15:36