Kivy开发:如何动态调整ScrollView嵌套场景下的BoxLayout高度
问题根因
你当前的ModelSpecifications布局仅在初始化时设置了一次固定高度,添加子按钮后没有主动更新高度值,因此无法动态适配内容。同时KV代码中padding属性拼写错误(写为pading),会导致边距设置不生效。
解决方案
你可以在每次添加完所有按钮后,直接在Python代码中给ModelSpecifications实例的height属性赋值,值可以是你从其他函数获取的动态高度变量,也可以根据子组件数量自动计算适配高度。
具体修改步骤
- 导入dp单位转换工具,保证不同分辨率设备上尺寸一致
- 修正KV文件中的属性拼写错误
- 在
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
相关产品推荐
相关产品推荐

