如何在 BoxLayout 中垂直堆叠多行标签
How to stack multi-line labels vertically in BoxLayout
我正在尝试在 BoxLayout 内的 Kivy 上创建一堆多行标签。如何让 BoxLayout 根据其内容展开?现在 BoxLayout 正在挤压标签。
我不希望对多行标签大小进行硬编码,因为我希望每个标签都能够灵活地适应不同的文本行。
我的演示代码如下:
from kivy.app import App
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.gridlayout import GridLayout
from kivy.uix.scrollview import ScrollView
from kivy.uix.label import Label
from kivy.graphics import Color, Rectangle
class MyApp(App):
def build(self):
self.root = GridLayout(rows=1)
self.root.add_widget(Scroller())
return self.root
class Scroller(ScrollView):
def __init__(self):
ScrollView.__init__(self)
self.view = GridLayout(cols=1, size_hint=(1, None))
self.add_widget(self.view)
self.view.bind(minimum_height=self.view.setter("height"))
for i in range(20):
self.view.add_widget(MyWidget(i % 2 is 1))
class MyWidget(BoxLayout):
def __init__(self, odd, **kwargs):
super().__init__(**kwargs)
self.orientation = "vertical"
self.size_hint = (1, None)
self.odd = odd
for i in range(3):
ll = Label(text=f"I am line\nNumber {i + 1}")
self.add_widget(ll)
self.bind(pos=self.format_background_color)
self.bind(size=self.format_background_color)
def format_background_color(self, *args):
with self.canvas.before:
if self.odd:
Color(0.0, 0.0, 0.2, mode="rgb")
else:
Color(0.0, 0.0, 0.8, mode="rgb")
Rectangle(pos=self.pos, size=self.size)
MyApp().run()
如果您添加到 MyWidget
的 Label
具有固定数量的 text
,您可以为 MyWidget
的 height
设置一个特定值作为 self.height = "150dp"
(根据您的需要进行调整)。
否则,如果您希望 MyWidget
的 height
足以容纳其子项(此处为 Label
),则将其设置为其 minimum_height
。您还必须将每个 Label
的 height
设置为其纹理高度。
因此,您修改后的 MyWidget
class 现在应该看起来像,
class MyWidget(BoxLayout):
def __init__(self, odd, **kwargs):
super().__init__(**kwargs)
self.orientation = "vertical"
self.size_hint_y = None
self.odd = odd
self.bind(
pos = self.format_background_color,
size = self.format_background_color,
minimum_height = self.setter("height")
)
for i in range(3):
ll = Label(text=f"I am line\nNumber {i + 1}")
ll.bind(texture_size=self.resize_label)
self.add_widget(ll)
def resize_label(self, instance, value):
instance.size_hint_y = None
instance.height = value[1]
...
您还可以利用 padding
和 spacing
作为,
class MyWidget(BoxLayout):
def __init__(self, odd, **kwargs):
super().__init__(**kwargs)
self.orientation = "vertical"
self.size_hint_y = None
self.padding = "10dp"
self.spacing = "10dp"
...
我正在尝试在 BoxLayout 内的 Kivy 上创建一堆多行标签。如何让 BoxLayout 根据其内容展开?现在 BoxLayout 正在挤压标签。
我不希望对多行标签大小进行硬编码,因为我希望每个标签都能够灵活地适应不同的文本行。
我的演示代码如下:
from kivy.app import App
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.gridlayout import GridLayout
from kivy.uix.scrollview import ScrollView
from kivy.uix.label import Label
from kivy.graphics import Color, Rectangle
class MyApp(App):
def build(self):
self.root = GridLayout(rows=1)
self.root.add_widget(Scroller())
return self.root
class Scroller(ScrollView):
def __init__(self):
ScrollView.__init__(self)
self.view = GridLayout(cols=1, size_hint=(1, None))
self.add_widget(self.view)
self.view.bind(minimum_height=self.view.setter("height"))
for i in range(20):
self.view.add_widget(MyWidget(i % 2 is 1))
class MyWidget(BoxLayout):
def __init__(self, odd, **kwargs):
super().__init__(**kwargs)
self.orientation = "vertical"
self.size_hint = (1, None)
self.odd = odd
for i in range(3):
ll = Label(text=f"I am line\nNumber {i + 1}")
self.add_widget(ll)
self.bind(pos=self.format_background_color)
self.bind(size=self.format_background_color)
def format_background_color(self, *args):
with self.canvas.before:
if self.odd:
Color(0.0, 0.0, 0.2, mode="rgb")
else:
Color(0.0, 0.0, 0.8, mode="rgb")
Rectangle(pos=self.pos, size=self.size)
MyApp().run()
如果您添加到 MyWidget
的 Label
具有固定数量的 text
,您可以为 MyWidget
的 height
设置一个特定值作为 self.height = "150dp"
(根据您的需要进行调整)。
否则,如果您希望 MyWidget
的 height
足以容纳其子项(此处为 Label
),则将其设置为其 minimum_height
。您还必须将每个 Label
的 height
设置为其纹理高度。
因此,您修改后的 MyWidget
class 现在应该看起来像,
class MyWidget(BoxLayout):
def __init__(self, odd, **kwargs):
super().__init__(**kwargs)
self.orientation = "vertical"
self.size_hint_y = None
self.odd = odd
self.bind(
pos = self.format_background_color,
size = self.format_background_color,
minimum_height = self.setter("height")
)
for i in range(3):
ll = Label(text=f"I am line\nNumber {i + 1}")
ll.bind(texture_size=self.resize_label)
self.add_widget(ll)
def resize_label(self, instance, value):
instance.size_hint_y = None
instance.height = value[1]
...
您还可以利用 padding
和 spacing
作为,
class MyWidget(BoxLayout):
def __init__(self, odd, **kwargs):
super().__init__(**kwargs)
self.orientation = "vertical"
self.size_hint_y = None
self.padding = "10dp"
self.spacing = "10dp"
...