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

Kivy开发:如何动态调整ScrollView嵌套场景下的BoxLayout高度

问题根因

你当前的ModelSpecifications布局仅在初始化时设置了一次固定高度,添加子按钮后没有主动更新高度值,因此无法动态适配内容。同时KV代码中padding属性拼写错误(写为pading),会导致边距设置不生效。

解决方案

你可以在每次添加完所有按钮后,直接在Python代码中给ModelSpecifications实例的height属性赋值,值可以是你从其他函数获取的动态高度变量,也可以根据子组件数量自动计算适配高度。

具体修改步骤

  1. 导入dp单位转换工具,保证不同分辨率设备上尺寸一致
  2. 修正KV文件中的属性拼写错误
  3. 在btn10方法添加完所有子按钮后,给cal5.height赋值动态高度

修改后完整代码

main.py

from kivy.app import App
from kivy.uix.gridlayout import GridLayout
from kivy.uix.widget import Widget
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.scrollview import ScrollView
from kivy.uix.spinner import Spinner
from kivy.uix.button import Button
from kivy.uix.label import Label
from kivy.properties import ObjectProperty, StringProperty, BooleanProperty
from kivy.properties import ListProperty
from kivy.metrics import dp # 新增导入dp转换
from collections import OrderedDict

data1=["mother","father","son"]
data2=["uncle","aunt","grandfather"]
data3=["jack","mike","simon"]
data4=["1898","1975","1985","1885"]

class MainWidget(Widget):

    an0=tuple(list(OrderedDict.fromkeys(data1)))
    cal5= ObjectProperty()

    def btn10(self,text):
        if self.cal5:
            self.cal5.parent.remove_widget(self.cal5)
        self.cal5 = ModelSpecifications()

        a=data2
        b=data3
        c=data4

        mi=[]
        n=0
        while n < len(a):
            aba=(str(a[n])+"\n"+str(b[n])+"\n"+str(c[n]))
            mi.append(aba)
            n+=1

        # 按钮高度统一设为60dp,适配3行文本
        btn_height = dp(60)
        for i in mi:
            self.b1=Button(text=str(i),size_hint=(1,None),height=btn_height)
            self.cal5.add_widget(self.b1)
        
        # 动态赋值高度,此处可以替换为你从其他函数获取的高度值
        # 方式1:使用自定义动态高度变量,假设你的函数返回高度为200dp
        # custom_height = get_height_from_other_func() # 你的自定义高度函数
        # self.cal5.height = dp(custom_height)

        # 方式2:自动计算适配所有子组件的高度
        spacing = dp(10) # 和kv中设置的spacing一致
        padding = dp(10) # 和kv中设置的padding一致
        total_height = len(mi)*btn_height + (len(mi)-1)*spacing + 2*padding
        self.cal5.height = total_height

        self.ids.scd.add_widget(self.cal5, index=3)

class SecondPage(ScrollView):
    pass

class ModelSpecifications(BoxLayout): 
    def __init__(self, **kwargs):
        super().__init__(**kwargs)
        self.size_hint=(1,None)
        # 移除固定初始高度,改为后续动态赋值
        # 如果需要默认高度可以在这里保留初始值

class Calculation(GridLayout):
    pass   

class MyApp(App):
    pass

MyApp().run()

my.kv

#:import C kivy.utils.get_color_from_hex


MainWidget:
<MainWidget>:
    ScreenManager:
        id: scmanager
        size: root.width, root.height
        Screen:
            id: scndpage
            name: "second"
            SecondPage:
                Calculation:
                    id:scd            
                    cols:1 
                    height: self.minimum_height 
                    row_default_height: "70dp"
                    size_hint_y: None
                    spacing:"10dp"
                    canvas.before:
                        Rectangle:
                            pos: self.pos
                            size: self.size
                    BoxLayout:
                        size_hint: 1, None
                        height: "50dp"
                        padding:"10dp"
                        spacing:"10dp"
                        orientation: "vertical"
                        BoxLayout:
                            orientation: "horizontal"
                            Label:
                                text:"Name:"
                                color: 0,0,0,1
                            TextInput:
                                text:"---"
                                color: 0,0,0,1
                            Label:
                                text:"Surname:"
                                color: 0,0,0,1
                            TextInput:
                                text:"-----"
                                color: 0,0,0,1
                    BoxLayout:
                        id:scdd
                        size_hint: 1, None
                        height: "100dp"
                        orientation: "vertical"
                        BoxLayout:
                            size_hint: 1, None
                            height: "50dp"
                            orientation: "horizontal"
                            Label:
                                text: " Sellection:"
                                color: 0,0,0,1
                            Spinner:
                                text: 'Home'
                                values: root.an0
                                on_text: app.root.btn10(self.text)                                       
                    Button:
                        text:" Calculate"
                    Button:
                        text:"Sellect"
                    Button:
                        text:"Back"

<ModelSpecifications>:
    id:anss                
    padding:"10dp" # 修正拼写错误
    spacing:"10dp"
    orientation: "vertical"
    canvas.before:
        Color:
            rgba: (C('EBE4E4'))
        RoundedRectangle:
            size: self.size
            pos: self.pos
            radius: [15]

补充说明

如果不需要自定义高度,希望布局永远自动适配子组件总高度,可以直接在ModelSpecifications的__init__方法中添加绑定:

self.bind(minimum_height=self.setter('height'))

添加后无需手动计算高度,新增/删除子组件时布局高度会自动调整。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.30 14:15:03