【发布时间】:2017-05-14 17:34:32
【问题描述】:
请考虑以下代码:
Builder.load_string(
"""
<TestView>:
canvas.before:
Color:
rgba: 0, 1, 0, 1
Rectangle:
pos: self.pos
size: self.size
""")
class TestView(GridLayout):
def __init__(self, **kwargs):
super(TestView, self).__init__(**kwargs)
self.cols = 1
self.spacing = 20
self.add_widget(Label(text="I'm on the TestView", height=80 ))
class TestScreen(Screen):
def __init__(self, **kwargs):
super(TestScreen, self).__init__(**kwargs)
self.content_grid_layout = GridLayout(cols=1, spacing=20, size_hint_y=None)
self.content_grid_layout.bind(minimum_height=self.content_grid_layout.setter('height'))
self.content_grid_layout.add_widget(Label(text="A"))
self.content_grid_layout.add_widget(Label(text="B"))
self.content_grid_layout.add_widget(TestView())
self.scroll_view = ScrollView(size_hint=(1, 1), size=(self.width, self.height))
self.scroll_view.add_widget(self.content_grid_layout)
self.add_widget(self.scroll_view)
sm = ScreenManager()
sm.add_widget(TestScreen(name="test_screen"))
class TestApp(App):
def build(self):
return sm
if __name__ == '__main__':
TestApp().run()
(我省略了导入以节省空间)。所以我在这里的具体问题是我希望 TestView 的背景被涂成绿色,但它不在这里。如果您只是将 TestView 直接添加到 Screen 的布局中,即更改 TestScreen 的 init 以执行以下操作:
self.content_grid_layout = GridLayout(cols=1, spacing=20, size_hint_y=None)
self.content_grid_layout.add_widget(TestView())
self.add_widget(self.content_grid_layout)
但是,我需要将我的内容放在此处的 ScrollView 上。所以我还注意到,如果我只是注释掉这一行:
self.content_grid_layout.bind(minimum_height=self.content_grid_layout.setter('height'))
从原始代码来看,一切似乎都按预期工作,并且 TestView 的背景被涂成绿色。但是,如果我这样做,结果 ScrollView 并没有达到我的预期(它不会滚动)。
如果我给 TestView 一个明确的高度,那么一切都会按预期工作,例如添加:
self.size_hint_y = None
self.height = 40
到 TestView 初始化。所以我猜问题是不是真的知道给TestView的高度是多少,但是奇怪的是能够把标签放在大约正确的位置,但不能画背景,或者把它画在屏幕上或其他东西上。无论如何,对 TestView 进行硬编码对我不起作用,因为 IRL 它会包含一些高度不同的动态内容。
我觉得在一个理智的世界里,布局的高度就是其内容的高度,除非另有说明,但也许这就是我。我想如果我可以根据其内容调整 TestView 的大小,那么我会得到我期望的行为吗?
编辑:
好的,我想我可以按照这里描述的策略让它做我想做的事:https://groups.google.com/d/msg/kivy-users/xRl2l8-1qLs/zzpk-QG4C0MJ (特别是那里描述的 CustomGridLayout,我猜这就像我的 TestView)。
所以基本的想法似乎是我们最初将自定义 GridLayout (TestView) 设置为零高度,然后为我们添加的每个子项手动更新其高度,如下所示:
class TestView(GridLayout):
def __init__(self, **kwargs):
super(TestView, self).__init__(**kwargs)
self.cols = 1
self.spacing = 20, 20
self.size_hint_y = None
self.height = 0
self.height = self.height + 30 + self.spacing[1]
self.add_widget(Label(text="I'm on the TestView 1", size_hint_y=None, height=30))
self.height = self.height + 30 + self.spacing[1]
self.add_widget(Label(text="I'm on the TestView 2", size_hint_y=None, height=30))
self.height = self.height + 30 + self.spacing[1]
self.add_widget(Label(text="I'm on the TestView 3", size_hint_y=None, height=30))
我不会撒谎,我认为这很丑陋。当我向它添加一个小部件时,布局似乎应该能够计算出它的新高度,而不必像这样用勺子喂它。无论如何,它似乎工作。如果有人这样做的方式并不可怕,我将保留这个问题。
【问题讨论】: