2013-09-07 2 views
4

kvy에 ver 텍스트가 있습니다. 텍스트의 수량에 따라 조정 동적 높이가 달라집니다.가변 높이 텍스트 속성 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() 

텍스트의 양에 따라 그리드 레이 아웃 조정의 레이블 높이 높이 행이 필요합니다.

답변

0

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 

예 :

내가 thopiekar의 도움으로 해결책을 발견
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() 
0

.

필요한 경우. 지금까지 나는이 방법없이 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() 

그리고 완벽하게 작동한다 !!!!!

4

이미 제안 된 해결책이 있지만, 나는 그들이 일을하는 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_lenght in range(0, 80, 20): 
      l = Label(
       text='word ' * text_lenght, 
       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() 
0

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