【发布时间】:2020-05-09 22:25:26
【问题描述】:
我正在尝试将小部件添加到 kivy 滚动视图。滚动视图工作正常,但是当我尝试在滚动视图底部添加小部件时,滚动视图会自动调整其 scroll_y。由于滚动视图跳跃,这看起来很糟糕!在我看来,这是滚动视图的常见行为。我如何编辑或设置滚动视图,以便用户可以在滚动视图不改变位置的情况下继续滚动。 提前致谢!
【问题讨论】:
标签: scroll kivy scrollview kivy-language
我正在尝试将小部件添加到 kivy 滚动视图。滚动视图工作正常,但是当我尝试在滚动视图底部添加小部件时,滚动视图会自动调整其 scroll_y。由于滚动视图跳跃,这看起来很糟糕!在我看来,这是滚动视图的常见行为。我如何编辑或设置滚动视图,以便用户可以在滚动视图不改变位置的情况下继续滚动。 提前致谢!
【问题讨论】:
标签: scroll kivy scrollview kivy-language
是的,这是正常的ScrollView 行为。该行为是因为ScrollView 不调整scroll_y 值,这在大多数情况下会导致滚动。您可以通过计算一个新的scroll_y 值来避免这种行为,该值旨在保持视口的相同部分在ScrollView 中可见。这很容易做到,只要添加的Widget 具有已知的height。下面是一个例子:
from functools import partial
from kivy.app import App
from kivy.clock import Clock
from kivy.lang import Builder
from kivy.uix.label import Label
kv = '''
BoxLayout:
orientation: 'vertical'
Button:
text: 'add'
on_release: app.add_new_widget()
ScrollView:
id: scroll
BoxLayout:
id: box
orientation: 'vertical'
size_hint_y: None
height: self.minimum_height
'''
class TestApp(App):
def build(self):
self.count = 0
return Builder.load_string(kv)
def add_new_widget(self):
vp_height = self.root.ids.scroll.viewport_size[1]
sv_height = self.root.ids.scroll.height
# add a new widget (must have preset height)
label = Label(text='Widget #' + str(self.count), size_hint=(1, None), height=50)
self.root.ids.box.add_widget(label)
self.count += 1
if vp_height > sv_height: # otherwise there is no scrolling
# calculate y value of bottom of scrollview in the viewport
scroll = self.root.ids.scroll.scroll_y
bottom = scroll * (vp_height - sv_height)
# use Clock.schedule_once because we need updated viewport height
# this assumes that new widgets are added at the bottom
# so the current bottom must increase by the widget height to maintain position
Clock.schedule_once(partial(self.adjust_scroll, bottom+label.height), -1)
def adjust_scroll(self, bottom, dt):
vp_height = self.root.ids.scroll.viewport_size[1]
sv_height = self.root.ids.scroll.height
self.root.ids.scroll.scroll_y = bottom / (vp_height - sv_height)
TestApp().run()
add_new_widget() 方法在每次调用时都会添加另一个Label,并且新的Label 具有指定的height(本例中为50)。如有必要,将调用 adjust_scroll() 方法,并计算一个新的 scroll_y 以防止 ScrollView 滚动。
【讨论】: