Kivy中Label间距异常及文件动态添加Label的问题咨询
问题1:调整CheckWordsMenu中Label的间距
你的CheckWordsMenu里承载Label的GridLayout设置了size_hint: 0.8, 0.01,高度仅为窗口高度的1%(600*0.01=6px),远不足以容纳两个Label,导致布局自动拉伸,spacing:3的设置失效。同时Label的texture_size: 'size'是错误写法,无法正确适配文本尺寸。
修改方案:
- 给承载Label的GridLayout设置合理的
size_hint_y(比如0.8),并嵌套进ScrollView,方便内容过多时滚动; - 修正Label的尺寸配置,让文本正常显示;
- 确保
spacing:3的间距设置生效。
问题2:读取文件内容并自动新增Label
需要实现以下核心逻辑:
- 在CheckWordsMenu中添加动态GridLayout用于承载所有单词Label;
- 编写文件读取方法,将每行内容转为Label添加到布局;
- 保存新单词时触发CheckWordsMenu更新内容;
- 进入CheckWordsMenu时自动加载最新文件内容。
修改后的完整代码
from kivy.config import Config Config.set("graphics", "resizable", 0) Config.set("graphics", "width", 300) Config.set("graphics", "height", 600) from kivy.app import App from kivy.uix.button import Button from kivy.uix.label import Label from kivy.uix.textinput import TextInput from kivy.uix.screenmanager import Screen, ScreenManager, SlideTransition from kivy.uix.gridlayout import GridLayout from kivy.uix.scrollview import ScrollView from kivy.lang import Builder Builder.load_string(''' <EngAppMenu>: background_normal: '' background_color: (43/255, 61/255, 91/255, 1) canvas.before: Color: rgba: self.background_color Rectangle: size: self.size pos: self.pos GridLayout: cols: 1 pos_hint: {'top': 0.95, 'center_x': 0.5} spacing: 10 size_hint: 0.72, 0.18 Button: text: "Check words" background_normal: '' background_color: (26/255, 45/255, 64/255, 1) on_press: root.manager.current = 'checkwords' Button: text: "Add words" background_normal: '' background_color: (26/255, 45/255, 64/255, 1) on_press: root.manager.current = 'addwords' <AddWordsMenu>: background_normal: '' background_color: (43/255, 61/255, 91/255, 1) canvas.before: Color: rgba: self.background_color Rectangle: size: self.size pos: self.pos GridLayout: cols: 1 pos_hint: {'top': 0.95, 'center_x': 0.5} spacing: 8 size_hint: 0.8, 0.2 TextInput: multiline: False hint_text: "Original word" id: eng_words on_text_validate: translation_words.focus=True TextInput: multiline: False hint_text: "Translation word" id: translation_words GridLayout: cols: 1 pos_hint: {'top': 0.73, 'center_x': 0.5} spacing: 8 size_hint: 0.8, 0.08 Button: text: "Save" background_normal: '' background_color: (26/255, 45/255, 64/255, 1) on_press: app.save(eng_words.text, translation_words.text) eng_words.text = "" translation_words.text = "" GridLayout: cols: 1 pos_hint: {'top': 0.1, 'center_x': 0.5} spacing: 8 size_hint: 0.8, 0.07 Button: text: "Menu" background_normal: '' background_color: (26/255, 45/255, 64/255, 1) on_press: root.manager.current = 'menu' <CheckWordsMenu>: background_normal: '' background_color: (43/255, 61/255, 91/255, 1) canvas.before: Color: rgba: self.background_color Rectangle: size: self.size pos: self.pos GridLayout: cols: 1 pos_hint: {'top': 0.95, 'center_x': 0.5} spacing: 8 size_hint: 0.8, 0.07 Button: text: "Menu" background_normal: '' background_color: (26/255, 45/255, 64/255, 1) on_press: root.manager.current = 'menu' ScrollView: pos_hint: {'top': 0.93, 'center_x': 0.5} size_hint: 0.8, 0.8 GridLayout: id: words_layout cols: 1 spacing: 3 size_hint_y: None height: self.minimum_height padding: 5 ''') class EngAppMenu(Screen, GridLayout): pass class AddWordsMenu(Screen, GridLayout): pass class CheckWordsMenu(Screen, GridLayout): def on_enter(self, *args): # 进入界面时加载最新单词 self.load_words() def load_words(self): # 清空现有Label self.ids.words_layout.clear_widgets() try: # 读取英文和翻译文件 with open('englishwords.txt', 'r', encoding='utf_8') as eng_file: eng_words = [line.strip() for line in eng_file if line.strip()] with open('translationwords.txt', 'r', encoding='utf_8') as trn_file: trn_words = [line.strip() for line in trn_file if line.strip()] # 配对单词并创建Label for eng, trn in zip(eng_words, trn_words): word_label = Label( text=f"{eng} - {trn}", size_hint_y=None, height=30, halign='left', valign='center' ) word_label.bind(texture_size=word_label.setter('size')) self.ids.words_layout.add_widget(word_label) except FileNotFoundError: # 文件不存在时提示 self.ids.words_layout.add_widget( Label(text="暂无单词,请先添加", size_hint_y=None, height=30) ) sm = ScreenManager() sm.add_widget(EngAppMenu(name='menu')) sm.add_widget(AddWordsMenu(name="addwords")) sm.add_widget(CheckWordsMenu(name="checkwords")) class EngApp(App): def build(self): return sm def save(self, engw, trnw): if engw.strip() and trnw.strip(): # 写入文件 with open('englishwords.txt','a', encoding='utf_8') as eng: eng.write(engw.strip() + "\n") with open('translationwords.txt','a', encoding='utf_8') as trn: trn.write(trnw.strip() + "\n") # 更新CheckWordsMenu的内容 check_screen = self.root.get_screen('checkwords') check_screen.load_words() if __name__ == '__main__': EngApp().run()
关键修改说明
Label间距修复:
- 将承载Label的GridLayout放入ScrollView,设置
size_hint_y: None和height: self.minimum_height,让高度自适应内容; - Label设置
size_hint_y: None和固定height,确保spacing:3的间距设置生效; - 绑定
texture_size到Label的size,让Label宽度适配文本内容。
- 将承载Label的GridLayout放入ScrollView,设置
文件读取与自动更新:
- 在
CheckWordsMenu的on_enter方法中调用load_words,进入界面自动加载最新内容; load_words方法读取两个文件的内容,配对后创建Label添加到布局;save方法中保存成功后,主动调用CheckWordsMenu的load_words方法更新界面。
- 在
内容的提问来源于stack exchange,提问作者wizelm
相关产品推荐
相关产品推荐

