4

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

テキストの量に応じて、ラベルの高さまたはグリッドレイアウトの高さの行を調整したい。

4

4 に答える 4

1

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

そして完璧に動作します!!!!!

于 2013-09-08T05:23:42.717 に答える
0

text.size()メソッドはheightLabel の属性を変更していません。テキストが長すぎると、以下のコンテンツと重複します。

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()
于 2013-09-08T02:49:08.393 に答える
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()
于 2014-07-31T13:05:33.347 に答える