Text 如何调整可变高度文本属性kivy?

Text 如何调整可变高度文本属性kivy?,text,label,grid-layout,kivy,Text,Label,Grid Layout,Kivy,我有一篇很长的kivy文本。我想调整动态高度取决于文本的数量 我的密码是这个 import kivy from kivy.app import App from kivy.uix.label import Label from kivy.uix.gridlayout import GridLayout class DynamicHeight(App):y def build(self): grid = gl = GridLayout(cols=1)

我有一篇很长的kivy文本。我想调整动态高度取决于文本的数量

我的密码是这个

import kivy
from kivy.app import App 
from kivy.uix.label import Label
from kivy.uix.gridlayout import GridLayout


class DynamicHeight(App):y
    def build(self):
        grid = gl = GridLayout(cols=1)

        for i in range(3):
            l = Label(text='Text a longer line line line line line line line line', halign='left',text_size=(300, None))
            grid.add_widget(l)

        return grid

DynamicHeight().run()
我希望标签的高度或网格布局的高度行根据文本量进行调整。

text.size()
方法不会更改标签的高度。如果文本太长,将与以下内容重叠:

from kivy.app import App 
from kivy.uix.label import Label
from kivy.uix.button import Button
from kivy.uix.gridlayout import GridLayout


class DynamicHeight(App):
    def build(self):
        layout = GridLayout(cols=1, spacing=20)

        l = Label(text='! '*100, text_size=(10, None),  size_hint_y=None, height=10)
        b = Button(text='...', size_hint_y=None)
        layout.add_widget(l)
        layout.add_widget(b)

        return layout

DynamicHeight().run()
您需要计算文本的高度,并手动将其设置为
height
属性。我不知道有什么好的干净的方法来做这件事。这是一种肮脏的方式:

before = label._label.render()
label.text_size=(300, None)
after = label._label.render()
label.height = (after[1]/before[1])*before[1] # ammount of rows * single row height
例如:

from kivy.app import App 
from kivy.uix.label import Label
from kivy.uix.gridlayout import GridLayout
from kivy.uix.scrollview import ScrollView

class DynamicHeight(App):
    def build(self):
        layout = GridLayout(cols=1, size_hint_y=None, spacing=20)
        layout.bind(minimum_height=layout.setter('height'))
        for i in xrange(1, 20):
            l = Label(text='Text ' * (i*10), text_size=(300, None), size_hint_y=None)

            # calculating height here 
            before = l._label.render()
            l.text_size=(300, None)
            after = l._label.render()
            l.height = (after[1]/before[1])*before[1] # ammount of rows * single row height
            # end

            layout.add_widget(l)
        root = ScrollView()
        root.add_widget(layout)
        return root

DynamicHeight().run()

在thopiekar的帮助下,我找到了解决办法

对于那些需要这个的人。到目前为止,我还没有发现没有这种方法的kivy do

import kivy
from kivy.app import App 
from kivy.uix.label import Label
from kivy.uix.gridlayout import GridLayout
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.button import Button


class MultiLineLabel(Button):
    def __init__(self, **kwargs):
        super(MultiLineLabel, self).__init__( **kwargs)
        self.text_size = self.size
        self.bind(size= self.on_size)
        self.bind(text= self.on_text_changed)
        self.size_hint_y = None # Not needed here

    def on_size(self, widget, size):
        self.text_size = size[0], None
        self.texture_update()
        if self.size_hint_y == None and self.size_hint_x != None:
            self.height = max(self.texture_size[1], self.line_height)
        elif self.size_hint_x == None and self.size_hint_y != None:
            self.width  = self.texture_size[0]

    def on_text_changed(self, widget, text):
        self.on_size(self, self.size)


class DynamicHeight(App):
    def build(self):
        grid = GridLayout(cols=1,size_hint_x=None, width="300dp")

        l=['This Text very long, should add multiple lines, automatically. This Text very long, should add multiple lines, automatically', 'One line']

        for i in l:
            l = MultiLineLabel(text=i)
            grid.add_widget(l)
        return grid

DynamicHeight().run()

而且效果非常好

虽然已经提出了一些解决方案,但我觉得它们没有利用kivy的做事方式,而且这种方式更干净。您需要将文本大小绑定到可用宽度,并将小部件的高度绑定到渲染纹理大小

从kivy.app导入应用
从kivy.uix.label导入标签
从kivy.uix.gridlayout导入gridlayout
从kivy.uix.floatlayout导入floatlayout
类别MyApp(应用程序):
def生成(自):
root=FloatLayout()
b=网格布局(
cols=1,
位置提示={
"center_x":.5,,
“center_y”:.5},
大小提示=(无,无),
间距=20,
宽度=200)
b、 绑定(最小高度=b.setter('height'))
root.add_小部件(b)
对于范围(0、80、20)内的文本长度:
l=标签(
text='word'*文本长度,
大小(提示(y=无)
l、 绑定(宽度=λs,w:
s、 setter('text_size')(s,(w,None)))
l、 绑定(纹理大小=l.setter('size'))
b、 添加小部件(l)
返回根
如果uuuu name uuuuuu='\uuuuuuu main\uuuuuuu':
MyApp().run()

继tshirtman的回答之后,我创建了在kv-lang中执行相同操作的代码。这可能会更清楚一些,因为您不需要分析回调函数

实际情况是,标签的宽度根据布局设置,而高度则设置为文本的纹理大小。因此,随着文本字符串变长,纹理只能在高度上增长,我们可以通过将boxlayout的高度设置为my_label.height来应用上面的方法

# -*- coding:utf8 -*-

from kivy.lang import Builder
from kivy.app import App
from kivy.uix.label import Label
from kivy.uix.boxlayout import BoxLayout
from kivy.properties import StringProperty
from kivy.core.window import Window
Window.size = (400, 700)

PLACEHOLDER_TEXT = u'''The bindings illustrated in tshirtman's example are created automatically when using kv-lang.
Notice how the "id: my_label" allows us to access the Label's attributes in the BoxLayout's height declaration.'''

kv_string = """
<Example>:
    orientation: 'vertical'
    BoxLayout:
        # colored background for affected area:
        canvas.before:
            Color:
                rgba: 0.3, .4, .4, .6
            Rectangle:
                pos: self.pos
                size: self.size
        size_hint_y: None
        height: my_label.height
        Label:
            id: my_label
            text: root.text
            font_size: '14dp'
            text_size: (self.width, None)
            size: self.texture_size
            valign: 'top'
            halign: 'left'
    BoxLayout:
        orientation: 'vertical'
        size_hint_y: 1
        canvas.before:
            Color:
                rgba: 0.9, .0, .5, .6
            Rectangle:
                pos: self.pos
                size: self.size
        TextInput:
            text: root.PLACEHOLDER_TEXT
            on_text: root.text = self.text
            text_size: self.size
            auto_indent: True
        Label:
            size_hint_y: None
            height: '50dp'
            text: 'String length: ' + str(len(root.text))
"""

Builder.load_string( kv_string )

class Example (BoxLayout ):
    PLACEHOLDER_TEXT = PLACEHOLDER_TEXT
    text = StringProperty(  )
    def __init__(self, **kwargs):
        super( Example, self).__init__(**kwargs)

class MyApp(App):
    def build(self):
        root = Example()
        return root

MyApp().run()
#-*-编码:utf8-*-
从kivy.lang导入生成器
从kivy.app导入应用程序
从kivy.uix.label导入标签
从kivy.uix.boxlayout导入boxlayout
从kivy.properties导入StringProperty
从kivy.core.window导入窗口
Window.size=(400700)
占位符_TEXT=u'''tshirtman示例中所示的绑定是在使用kv-lang时自动创建的。
注意“id:my_标签”如何允许我们访问BoxLayout高度声明中的标签属性
kv_字符串=”“
:
方向:“垂直”
盒子布局:
#受影响区域的彩色背景:
在以下情况之前:
颜色:
rgba:0.3、.4、.4、.6
矩形:
pos:self.pos
大小:self.size
尺寸提示:无
高度:我的标签高度
标签:
我的标签
text:root.text
字体大小:“14dp”
文本大小:(self.width,无)
大小:self.texture\u大小
valign:“顶级”
哈利格:“左”
盒子布局:
方向:“垂直”
尺寸提示:1
在以下情况之前:
颜色:
rgba:0.9,0,5,6
矩形:
pos:self.pos
大小:self.size
文本输入:
文本:root.PLACEHOLDER\u文本
on_text:root.text=self.text
文本大小:self.size
自动缩进:真
标签:
尺寸提示:无
高度:'50dp'
text:'字符串长度:'+str(len(root.text))
"""
建筑商。荷载串(千伏串)
类示例(BoxLayout):
占位符\文本=占位符\文本
text=StringProperty()
定义初始(自我,**kwargs):
超级(示例,self)。\uuuuu初始化(**kwargs)
类别MyApp(应用程序):
def生成(自):
root=Example()
返回根
MyApp().run()

新手问题。。为什么要为这个按钮创建子类?标签似乎没有大小属性。