【问题标题】:How I can adjust variable height text property kivy?如何调整可变高度文本属性 kivy?
【发布时间】:2013-09-11 07:35:12
【问题描述】:

我有一个很长的 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()

我要根据文字的多少调整那个label的高度或者gridlayout的行高。

【问题讨论】:

    标签: text label grid-layout kivy


    【解决方案1】:

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

    from kivy.app import App
    from kivy.uix.label import Label
    from kivy.uix.gridlayout import GridLayout
    from kivy.uix.floatlayout import FloatLayout
    
    
    class MyApp(App):
        def build(self):
            root = FloatLayout()
    
            b = GridLayout(
                cols=1,
                pos_hint={
                    'center_x': .5,
                    'center_y': .5},
                size_hint=(None, None),
                spacing=20,
                width=200)
            b.bind(minimum_height=b.setter('height'))
            root.add_widget(b)
    
            for text_length in range(0, 80, 20):
                l = Label(
                    text='word ' * text_length,
                    size_hint_y=None)
                l.bind(width=lambda s, w:
                       s.setter('text_size')(s, (w, None)))
                l.bind(texture_size=l.setter('size'))
                b.add_widget(l)
    
            return root
    
    
    if __name__ == '__main__':
        MyApp().run()
    

    【讨论】:

      【解决方案2】:

      在 thopiekar 的帮助下,我找到了解决方案。

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

      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()
      

      而且效果很好!!!!!!

      【讨论】:

      • 新手问题.. 为什么要为这个子类按钮?标签似乎没有 size 属性。
      【解决方案3】:

      text.size() 方法不会改变标签的height 属性。如果文字过长,会与下面的内容重叠:

      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()
      

      【讨论】:

        【解决方案4】:

        根据 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()
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2015-10-24
          • 1970-01-01
          • 1970-01-01
          • 2017-09-21
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多