首页 > 解决方案 > 在轮播中的幻灯片上的 Kivy 浮动上定位和换行文本,而不会溢出到相邻的幻灯片中

问题描述

我有一个看起来像婴儿书的 Kivy 旋转木马。每张幻灯片上都有一个浮动,每个浮动都有一张图片、一个标签和一些文本。有几个问题,文本溢出到相邻的幻灯片上,我无法让它自动换行和/或调整自身大小以保持在幻灯片上的浮动。

我已经阅读了很多文档,并尝试了很多关于 pos_hint 和 size_hint 以及 text_size 和 size 的东西,但没有任何东西能像我预期的那样工作。例如,参见thisthis以及thisthis

显示所有文本的宽视图

显示没有换行、没有调整大小和文本溢出的窄视图

代码如下。它很长,但大部分只是将小部件添加到父小部件。

import kivy 
from kivy.app import App
from kivy.core.window import Window
from kivy.uix.floatlayout import FloatLayout 
from kivy.uix.label import Label
from kivy.uix.image import AsyncImage 
from kivy.uix.carousel import Carousel 

def render_kivy_carousel(): 
    # Set the windows background colour.
    Window.clearcolor = (1, 1, 0, 1)
    # Create the book renditions root widget.
    bkr = Carousel() 
    bkr.width = 100
    bkr.loop = True
    # Add the page widgets.

    """PAGE 1
    """
    # Create the pages base widget
    flo = FloatLayout()

    # Build the image
    image = AsyncImage(source='https://wallpaperaccess.com/full/195082.jpg',
                allow_stretch = True,
                keep_ratio = True,
                size_hint = (0.5, 0.5),
                pos_hint = {'x': 0.25, 'y': 0.25},)
    flo.add_widget(image)

    # Build the label
    label = Label(text='Bee',
                color=(0,0,0,1),
                font_size=60,
                size_hint=(0.25, 0.25),
                pos_hint={'bottom': 1, 'left': 1},)
    flo.add_widget(label)
    
    # Build the text
    text = Label(text='The bee buzzes looking for flowers',
                color=(0,0,0,1),
                font_size=20,
                size_hint=(0.25, 0.25),
                pos_hint={'top': 1, 'right': 1},)
    flo.add_widget(text)
    bkr.add_widget(flo)

    """PAGE 2
    """
    # Create the pages base widget
    flo = FloatLayout()

    # Build the image
    image = AsyncImage(source='https://i.pinimg.com/originals/60/5b/c0/605bc0c0ef2645b43d64300bb2d82ed1.jpg',
                allow_stretch = True,
                keep_ratio = True,
                size_hint = (0.5, 0.5),
                pos_hint = {'x': 0.25, 'y': 0.25},)
    flo.add_widget(image)

    # Build the label
    label = Label(text='Beetle',
                color=(0,0,0,1),
                font_size=60,
                size_hint=(0.25, 0.25),
                pos_hint={'bottom': 1, 'left': 1},)
    flo.add_widget(label)
    
    # Build the text
    text = Label(text='The beetle looks at the sky',
                color=(0,0,0,1),
                font_size=20,
                size_hint=(0.25, 0.25),
                pos_hint={'top': 1, 'right': 1},)
    flo.add_widget(text)
    bkr.add_widget(flo)

    """PAGE 3
    """
    # Create the pages base widget
    flo = FloatLayout()

    # Build the image
    image = AsyncImage(source='https://encrypted-tbn0.gstatic.com/images?q=tbn%3AANd9GcQac3tmjWwO-o62Cm3iUAby6EVLWNG226UOJQ&usqp=CAU',
                allow_stretch = True,
                keep_ratio = True,
                size_hint = (0.5, 0.5),
                pos_hint = {'x': 0.25, 'y': 0.25},)
    flo.add_widget(image)

    # Build the label
    label = Label(text='Butterfly',
                color=(0,0,0,1),
                font_size=60,
                size_hint=(0.25, 0.25),
                pos_hint={'bottom': 1, 'left': 1},)
    flo.add_widget(label)
    
    # Build the text
    text = Label(text='The butterfly flaps its wings',
                color=(0,0,0,1),
                font_size=20,
                size_hint=(0.25, 0.25),
                pos_hint={'top': 1, 'right': 1},)
    flo.add_widget(text)
    bkr.add_widget(flo)

    # Return the root widget
    return bkr

# Create the App class 
class BookletApp(App): 
    def build(self): 
        return render_kivy_carousel()

# Run the App 
if __name__ == '__main__': 
    BookletApp().run()

有人可以让我知道正确的方法吗?我想要的是让文本保持在其幻灯片上的浮动内,并通过使用窗口/幻灯片包装和/或调整大小/缩放来做到这一点。

谢谢

标签: pythonkivy

解决方案


我编写了两个从标准 Kivy 小部件继承并具有所需行为的小部件。这可能不是最好的方法,但它确实有效。

文本换行小部件 此小部件的作用类似于“文本框”,其中的文本进行换行。您可以替换Button为,Label但按钮具有更多功能。的所有属性和方法Button都可用。

from kivy.uix.button import Button
...
class WrapBox(Button):
    def __init__(self, **kwargs):
        super().__init__(**kwargs)
        self.bind(
            width=lambda *x:
                self.setter('text_size')(self, (self.width, None)),
            texture_size=lambda *x: 
                self.setter('height')(self, self.texture_size[1]))
...
txtbox = WrapBox(text='wrap me up in your love baby')
txtbox.color = (0,0,0,1)
txtbox.font_size = 60

文本大小调整小部件 此小部件的作用类似于“文本框”,其中的文本会随着其所在窗口的大小而调整大小。如您所见,底层小部件实际上是ImageButton. 的所有属性和方法Button都可用。

from kivy.uix.image import Image
from kivy.uix.button import Button
...
class ResizeBox(Image):
    text = StringProperty('')
    def on_text(self, *args):
        # Just get large texture:
        lbl = Button(text=self.text)
        # Value that'll give texture bigger than screen size
        # Small values result in blur.
        lbl.font_size = '1000dp'  
        lbl.texture_update()
        # Set it to image, it'll be scaled to image size automatically
        self.texture = lbl.texture
...
txtbox = ResizeBox(text='resize me with your love baby')
txtbox.color = (0,0,0,1)
txtbox.font_size = 60

包装和调整大小


推荐阅读