So I have a ScrollView inside a GridLayout, but my Scroll view wont scroll. it moves to reveal more buttins, and then bounce back to the the top!
All the solutions online say just use self.size_hint_y = None
and just use self.height = self.minimum_height
and I have as you can see and it didnt stop the bouncing back...
from kivy.app import App
from kivy.uix.button import Button
from kivy.uix.gridlayout import GridLayout
from kivy.uix.scrollview import ScrollView
from kivy.uix.stacklayout import StackLayout
class MainWindow(GridLayout):
def __init__(self, **kwargs):
super(MainWindow, self).__init__(**kwargs)
self.cols = 2
self.rows = 1
self.layout1 = ScrollViewExample()
self.add_widget(self.layout1)
self.layout1.size_hint = ("0.3dp", None)
self.layout2 = MyGrid()
self.layout2.size_hint = (1, 1)
self.add_widget(self.layout2)
class SideMenuStack(StackLayout):
def __init__(self, **kwargs):
super(SideMenuStack, self).__init__(**kwargs)
# self.cols = 2
# self.rows = 50
self.size_hint_y = None
self.height = self.minimum_height
for i in range(100):
button = Button(text=str(i), size_hint=(None, None), size=("92dp", "92dp"))
self.add_widget(button)
class ScrollViewExample(ScrollView):
def __init__(self, **kwargs):
super(ScrollViewExample, self).__init__(**kwargs)
self.size_hint = (1, None)
self.height = 10000
self.layout1 = SideMenuStack()
self.layout1.size_hint = (1, None)
self.do_scroll_y = True
self.do_scroll_x = False
# self.effect_cls = 'ScrollEffect'
self.scroll_distance = 100000
self.add_widget(self.layout1)
class MyGrid(GridLayout):
pass
class GuiApp(App):
def build(self):
return MainWindow()
if __name__ == "__main__":
GuiApp().run()
Although your guess about self.size_hint_y = None
is right but setting self.height = self.minimum_height
in __init__
is not. Because during initialization the default values are applied. So what you need to do is, make the layout listen to any changes whenever any widget gets added to it (and thus increases its height).
Now this is done by bind
ing some callback to some attr. Here you can do it as,
# self.height = self.minimum_height
self.bind(minimum_height = self.setter("height"))
Thus you are actually setting a callback method (setter
, it is default in kivy) to listen to any changes in minimum_height
and then set this value as height
.
Some other changes included,
# self.layout1.size_hint = ("0.3dp", None)
self.layout1.size_hint = ("0.3dp", 1)
.
.
.
class ScrollViewExample(ScrollView):
def __init__(self, **kwargs):
...
# self.size_hint = (1, None)
# self.height = 10000
self.layout1 = SideMenuStack()
# self.layout1.size_hint = (1, None)
self.do_scroll_y = True
self.do_scroll_x = False
# self.effect_cls = 'ScrollEffect'
# self.scroll_distance = 100000 # Perhaps you don't need it.
...