10

At the moment this is my kv code that is not scrollable:

BoxLayout:
    id: bl
    orientation: 'vertical'
    padding: 10, 10
    row_default_height: '48dp'
    row_force_default: True
    spacing: 10, 10

    GridLayout:
        id: layout_content
        cols: 1
        row_default_height: '20dp'
        row_force_default: True
        spacing: 0, 0
        padding: 0, 0

        Label:
            text: 'You don''t have any downloads. Please add new download from Home screen'

How do you make the above kv code scrollable? I know that Kivy ScrollView only accept one child, and I have already make GridLayout to be child of a new ScrollView. But it's not working. Any suggestion?

swdev
  • 4,997
  • 8
  • 64
  • 106

2 Answers2

22

According to the documentation for ScrollView you have to disable at least one of the ScrollView's child size_hint:

<Controller>:
    layout_content: layout_content
    BoxLayout:
        id: bl
        orientation: 'vertical'
        padding: 10, 10
        row_default_height: '48dp'
        row_force_default: True
        spacing: 10, 10
        ScrollView:
            size: self.size
            GridLayout:
                id: layout_content
                size_hint_y: None
                cols: 1
                row_default_height: '20dp'
                row_force_default: True
                spacing: 0, 0
                padding: 0, 0

                Label:
                    text: "Lorem ipsum dolor sit amet"

And bind the layout's size to adapt itself:

# main.py

class Controller(FloatLayout):
    layout_content=ObjectProperty(None)

    def __init__(self, **kwargs):
        super(Controller, self).__init__(**kwargs)
        self.layout_content.bind(minimum_height=self.layout_content.setter('height'))
synw
  • 237
  • 3
  • 5
  • Almost exactly what I just did! :) Thanks.. @syntax_error? :D – swdev Nov 01 '14 at 22:14
  • 3
    Yeah almost: the devil is in the details, specially with kv stuff :) – synw Nov 02 '14 at 14:29
  • Got to say, I kinda hoping that Kivy-Designer become their main intention soon. It will definitely help us design the interface with ease. Unfortunately, that project seems to be in dormant state. I miss PyQt this way.. – swdev Nov 02 '14 at 15:45
  • 4
    Are you sure this is correct? I get an error `Traceback (most recent call last): File "main.py", line 24, in edlApp().run() File "/usr/lib/python2.7/dist-packages/kivy/app.py", line 766, in run root = self.build() File "main.py", line 20, in build return Controller() File "main.py", line 16, in __init__ self.layout_content.bind(minimum_height=self.layout_content.setter('height')) AttributeError: 'NoneType' object has no attribute 'bind' ` – amd Sep 08 '15 at 22:56
  • It should be `ScrollView:` <- With a colon – Rockbot Apr 08 '16 at 10:07
  • It worked for me, but i want to know why it is necessary to bind that ```minimum_height``` property? – Yash Patel Nov 01 '19 at 04:58
  • A simpler method is to bind the height to the minimum height inside the kv file: `height: self.minimum_height`. (see https://stackoverflow.com/a/47600781/6362595) – fgoudra Jan 18 '21 at 21:03
  • For anyone wanting a ScrollView that scrolls **horizontally** instead of **vertically**, use `width: self.minimum_width` instead. – Drake P Nov 01 '21 at 18:09
0

works and fixes issue of scrollview not resizing length with window when maximized. No kv for those needing it without

kivy.require('1.11.1')
      
class ScrollTest(ScrollView):
    def __init__(self,**kwargs):
        super().__init__(**kwargs)
    
        Window.bind(on_maximize=self.testing)
        
        self.size_hint = (1,None)
        self.pos_hint = {'center_x':0.5,'top': 1}
        self.size = (Window.width,Window.height)

        self.inside = GridLayout()
        self.inside.cols = 1
        self.inside.size_hint_y= None
        self.inside.spacing = 10
        
        self.inside.bind(minimum_height=self.inside.setter('height'))#checks when window maximized
        
        for i in range(1,5):
            self.submit = Button(text='something',size_hint_y=None, height=40)
            self.submit.bind(on_press=self.wPressed)
            self.inside.add_widget(self.submit)
        
        self.add_widget(self.inside)
        
    def wPressed(self,instance):
        self.submit = Button(text='something',size_hint_y=None, height=40)
        self.submit.bind(on_press=self.wPressed)
        self.inside.add_widget(self.submit)
            
    def testing(self,instance):
        self.size= (Window.width,Window.height)

        
class MyApp(App):
    def build(self):
        self.screen_manager = ScreenManager()
        
        '''Creation of login screen'''
        self.login_page = ScrollTest()
        screen = Screen(name= 'Login')
        screen.add_widget(self.login_page)
        self.screen_manager.add_widget(screen)
        
        return self.screen_manager


if __name__ == '__main__':
    MyApp().run()
Jaimil Patel
  • 1,301
  • 6
  • 13
rhowes
  • 1
  • from kivy.uix.scrollview import ScrollView from kivy.core.window import Window from kivy.uix.gridlayout import GridLayout from kivy.uix.button import Button – BananaMaster Aug 04 '20 at 11:53