如何在同一次程序运行中每次打开屏幕时都触发on_pre_enter事件
问题原因分析
- 你的
StackLayout放在ScrollView中未做自适应高度配置:ScrollView的子控件需要关闭高度的size_hint,绑定自身高度为最小内容高度,否则内容不会撑开,第二次进入时布局重算后高度为0,所有Label都不可见 - Label控件未配置自适应文本高度逻辑,你设置了
size_hint=(0.2, None)但未给height赋值,文本无法正常渲染 - 清空控件的时序放在
on_leave可能存在页面切换的异步时序问题,放在拉取数据前执行更稳妥
解决方案
1. 修改kv文件中StackLayout配置
给StackLayout加上高度自适应的配置:
< Reminders >: name: 'Reminders' FloatLayout: Label: text: "Notes" color: (0, 0.702, 0, 1) font_size: 50 pos_hint: {'x': 0.1, 'top': 1} size_hint: 0.2, 0.2 Button: size_hint: 0.07, 0.07 background_normal: 'plus.png' pos_hint: {'x': 0.78,'top': 0.94} on_release: root.add_note() ScrollView: size_hint: 0.96, 0.6 pos_hint: {'x': 0.02, 'top': 0.7} StackLayout: id: layout orientation: 'tb-lr' # 新增以下两行自适应配置 size_hint_y: None height: self.minimum_height padding: 10 spacing: 10 SmoothButton: text: "Back" pos_hint: {'x': 0.8, 'top': 0.15} size_hint: 0.15, 0.05 on_release: root.go_back()
2. 修改Python代码逻辑
调整清空逻辑的位置,给Label加上自适应高度的绑定:
class Reminders(Screen): collection = db['Notes'] def on_pre_enter(self, *args): # 先清空已有控件,放在拉取数据前更稳妥,可直接删除原来的on_leave方法 self.ids.layout.clear_widgets() records = self.collection.find({}) # 提前取布局宽度计算文本换行阈值 layout_width = self.ids.layout.width * 0.2 for record in records: existing_lbl = Label( text=record['Note'], size_hint=(0.2, None), text_size=(layout_width, None) ) # 绑定Label高度为文本内容实际高度 existing_lbl.bind(texture_size=lambda instance, size: setattr(instance, 'height', size[1])) self.ids.layout.add_widget(existing_lbl) def add_note(self): sm.switch_to(screens[6], direction='left') def go_back(self): sm.switch_to(screens[0], direction='right')
补充说明
如果存在屏幕旋转、尺寸变化时文本显示异常的问题,可以把Label的text_size改成动态绑定:
existing_lbl.bind( size=lambda instance, size: setattr(instance, 'text_size', (size[0], None)), texture_size=lambda instance, size: setattr(instance, 'height', size[1]) )
内容的提问来源于stack exchange,提问作者Jayanti
相关产品推荐
相关产品推荐

