Kivy中如何让新增标签与已有标签保持指定间距且显示在下方不重叠
问题原因
- 你当前使用
FloatLayout作为根布局,需要手动计算每个消息组件的位置,而你每次点击发送按钮时都会将位置参数a重置为0.95,导致新消息永远固定在屏幕顶部位置,自然会和历史消息重叠。 - 聊天消息属于纵向排列的列表类内容,使用
FloatLayout手动算位置的方案本身不合理,也不好适配不同屏幕、不同长度的消息。
解决方案
替换根布局为垂直方向的BoxLayout,拆分出专门存放历史消息的容器,BoxLayout会自动按添加顺序纵向排列子组件,无需手动计算位置,还可以嵌套ScrollView实现消息过多时滚动查看的效果。
修改后的Python代码
from kivy.app import App from kivy.uix.textinput import TextInput from kivy.uix.boxlayout import BoxLayout from kivy.properties import ObjectProperty class MyFL(BoxLayout): input = ObjectProperty(None) msg_container = ObjectProperty(None) def btn(self): if not self.input.text.strip(): return # 直接往消息容器里加组件,BoxLayout会自动排列在最下方 self.msg_container.add_widget(MyTextInput(text='> ' + self.input.text)) self.input.text = "" class MyTextInput(TextInput): pass class MyApp(App): def build(self): return MyFL() if __name__ == "__main__": MyApp().run()
修改后的Kv文件
<MyFL>: # 根布局设置为垂直排列 orientation: 'vertical' input: input msg_container: msg_container # 消息区域:嵌套ScrollView支持滚动 ScrollView: BoxLayout: id: msg_container orientation: 'vertical' # 高度自适应子组件总高度 size_hint_y: None height: self.minimum_height # 子组件顶部间距 padding: 5 # 子组件之间的间距 spacing: 5 # 底部输入栏:水平排列的BoxLayout放输入框和发送按钮 BoxLayout: orientation: 'horizontal' size_hint_y: 0.06 spacing: 5 padding: 2 TextInput: id: input multiline: False hint_text: "Say Something" font_size: 20 size_hint_x: 0.95 Button: text: "发送" size_hint_x: 0.05 on_press: root.btn() <MyTextInput>: size_hint: 1, None height: self.minimum_height readonly: True multiline:True # 可以加个背景色区分消息 background_color: 0.9, 0.9, 0.9, 1
额外优化
如果想要最新消息发送后自动滚动到底部,可以在btn方法添加完组件后补充一行代码:
from kivy.clock import Clock Clock.schedule_once(lambda _: setattr(self.msg_container.parent, 'scroll_y', 0), 0.1)
内容的提问来源于stack exchange,提问作者Tharak Enjamur
相关产品推荐
相关产品推荐

