基于窗口高度和宽度的 Kivy 缩放文本

2022-01-15 00:00:00 python kivy

问题描述

我想根据窗口高度缩放按钮或标签内的文本,但受窗口宽度限制.以下作品:

I want to scale a text inside a button or label based on the window height, but limited by window width. The following works:

font_size: self.height - dp(15)

但是文本可以超过按钮或标签的宽度,所以我想用类似的东西来限制它:

However the text can exceed the width of the button or label, so I want to limit it with something like:

font_size: self.height - dp(15) if self.texture_size[0] < self.width else (self.width*2)/(self.height+0.1)

不幸的是,当 >= texture_size[0] 时它会变小,但是当文本再次变小时,它是 <自我宽度.所以它最终陷入了一个循环,从而导致 [CRITICAL] [Clock] 错误.

Unfortunately this has to problem that when >= texture_size[0] it will become smaller, but then when the text is smaller again, it is < self.width. So it end up stuck in a loop, which results in [CRITICAL] [Clock] error.

为了给出更清晰的画面,红条中的文字应该尽可能大,但不要超过按钮宽度:

To give a more clear picture, the text in the red bar should be as big as possible, but not exceed the button width:


解决方案

如果文本太大,可以使用缩放变换来缩小文本,这样可以避免竞争:

You can use a scale transformation to shrink the text if it is too large, which will avoid the race:

<ScaleLabel@Label>:
    _scale: 1. if self.texture_size[0] < self.width else float(self.width) / self.texture_size[0]
    canvas.before:
        PushMatrix
        Scale:
            origin: self.center
            x: self._scale or 1.
            y: self._scale or 1.
    canvas.after:
        PopMatrix

不过,这确实会缩放画布上的所有内容.因此,如果您尝试绘制背景或其他内容,请确保它位于 PushMatrix/PopMatrix 之外.例如,如果你想将它与 Button 一起使用,你可以重写 Button 的 kv 规则:

This does scale everything on the canvas, however. So if you're trying to draw a background or something, make sure it is outside the PushMatrix/PopMatrix. For example, if you wanted to use this with a Button, you could rewrite Button's kv rules:

<-ScaleButton@Button>:
    state_image: self.background_normal if self.state == 'normal' else self.background_down
    disabled_image: self.background_disabled_normal if self.state == 'normal' else self.background_disabled_down
    _scale: 1. if self.texture_size[0] < self.width else float(self.width) / self.texture_size[0]
    canvas:
        Color:
            rgba: self.background_color
        BorderImage:
            border: self.border
            pos: self.pos
            size: self.size
            source: self.disabled_image if self.disabled else self.state_image
        PushMatrix
        Scale:
            origin: self.center
            x: self._scale or 1.
            y: self._scale or 1.
        Color:
            rgba: self.disabled_color if self.disabled else self.color
        Rectangle:
            texture: self.texture
            size: self.texture_size
            pos: int(self.center_x - self.texture_size[0] / 2.), int(self.center_y - self.texture_size[1] / 2.)
        PopMatrix

我创建了一个用法示例作为要点:https://gist.github.com/kived/862db38078170ec0ef83

I created a usage example as a gist: https://gist.github.com/kived/862db38078170ec0ef83

相关文章