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

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

需要实现以下核心逻辑:

  1. 在CheckWordsMenu中添加动态GridLayout用于承载所有单词Label;
  2. 编写文件读取方法,将每行内容转为Label添加到布局;
  3. 保存新单词时触发CheckWordsMenu更新内容;
  4. 进入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()

关键修改说明

  1. 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宽度适配文本内容。
  2. 文件读取与自动更新:

    • 在CheckWordsMenu的on_enter方法中调用load_words,进入界面自动加载最新内容;
    • load_words方法读取两个文件的内容,配对后创建Label添加到布局;
    • save方法中保存成功后,主动调用CheckWordsMenu的load_words方法更新界面。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.28 21:45:07