Skip to main content
 首页 » 编程设计

python之包装 Kivy 标签的文本

2025年05月04日11xing901022

所以我正在使用 Kivy GUI 编写一个程序,我真的不想使用 .kv 文件,而是将它全部写在 python 文件中。问题是在 MainScreen 类中,我想添加一些标签,但我无法根据窗口大小的变化使它们的文本换行。当我尝试 self.size 时,我只得到 100x100。我已经尝试了 Kivy 教程书中的所有建议,但没有任何效果。我知道我可以使用 \n 使文本多行或设置标准标签大小,但这不是真正的解决方案。我需要标签大小和文本来跟随整个窗口的变化和要换行的文本。

我已简化程序以仅关注此问题。

代码如下:

from kivy.app import App 
from kivy.uix.floatlayout import FloatLayout 
from kivy.uix.label import Label 
from kivy.graphics import Rectangle, Color 
 
 
class MainScreen(FloatLayout): 
    """MAIN WINDOW CLASS""" 
 
    def __init__(self, **kwargs): 
        super(MainScreen, self).__init__(**kwargs) 
 
        with self.canvas.before: 
            Color(0.988, 0.725, 0.074, 1, mode='rgba') 
            self.rect = Rectangle(pos=self.pos, size=self.size) 
        self.bind(size=self.update_rect) 
 
 
        #TITLE LABEL 
        self.add_widget(Label(text="A very Long Sentence that needs to be wrapped.", 
                              bold = True, 
                              font_size="20sp", 
                              pos_hint={'center_x': 0.5, 'center_y': .85}, 
                              size_hint=(None, None), 
                              halign="center", 
                              color=(0.055, 0.235, 0.541, 1))) 
 
    def update_rect(self, *args): 
        """FUNCTION TO UPDATE THE RECATANGLE OF CANVAS TO FIT THE WHOLE SCREEN OF MAINSCREEN ALWAYS""" 
        self.rect.pos = self.pos 
        self.rect.size = self.size 
 
class main(App): 
    """BUILDING THE APP""" 
    def build(self): 
        return MainScreen() 
 
if __name__ == "__main__": 
    main().run() 

谢谢。

请您参考如下方法:

首先,让我告诉你,你会让你的生活变得比它应该的更艰难,kv 并不难学,它允许 kivy 为你做更多繁重的工作。

在 kv 中,做类似的事情

Label: 
    text: 'blah blah ' * 1000 
    text_size: self.width, None 
    size_hint: 1, None 
    height: self.texture_size[1] 

通常可以解决这个问题,因为小部件正在使用其容器的整个宽度,并且 text_size 被绑定(bind)到它的宽度,每次此宽度更改时都会重新计算纹理,并且小部件的高度会自动适合纹理的高度。

现在,在没有 kv 的情况下做同样的事情。

  label = Label(text='blah blah '* 1000, size_hint=(1, None)) 
  label.bind( 
      width=lambda *x: label.setter('text_size')(label, (label.width, None), 
      texture_size=lambda *x: label.setter('height')(label, label.texture_size[1])) 

也就是说,你需要明确地告诉kivy它必须对标签的各种属性的变化使用react,并重新计算其他属性的值,而使用kv,它会自动检测到某些值依赖于其他值,并且会知道它需要自己绑定(bind)它们。

setter 是一个实用函数,它允许您避免在简单情况下定义 setter 函数,如果不是这样,在这里,您必须为每个绑定(bind)定义一个函数,并做一些事情比如其中的“self.text_size = self.width, None”,因为 lambda 不允许赋值。

kv 存在的原因之一是,它允许我们自己处理代码中的表达式,并检测依赖关系,如果你在 python 中完成所有这些,kivy 无法检测此类依赖关系,因为 python 本身不不关心它们,也不告诉 kivy。

现在,如果您想告诉我们为什么要避免使用 kv,请告诉我们,但我很确定这些原因是由于不了解 kv 而不是真正的问题。