Search code examples
python-3.xkivyscrollviewgrid-layoutoverlapping

Kivy : childeren GridLayouts of a ScrollView are overlapping with each other


I have kivy 1.11.1, Ubuntu 20.04 LTS, python 3.8 running on my laptop . I am beginner to kivy and currently working on kivy project, I am stuck on this problem of children gridlayout of scrollview getting overlapped. I have a scroll view with GridLayout and some labels as its children. GridLayout have one Label and a StackLayout which can have different number of entries for different row. Here is source code main.py.

from kivy.app import App
from kivy.lang.builder import Builder
from kivy.uix.floatlayout import FloatLayout
from  kivy.effects.scroll import ScrollEffect

kv = '''
#:import ScrollEffect kivy.effects.scroll.ScrollEffect
ScrollApp:

<ScrollApp>:
    ScrollView:
        size_hint: 1.0, 0.90
        pos_hint: {'center_y':0.5}
        padding: 22, 0, 22, 50
        spacing: 50
        effect_cls: ScrollEffect
        GridLayout:
            cols: 1
        #   id: streak_zone
            size_hint_y: None
            height: self.minimum_height
            row_force_default: True
            row_default_height: 400   
            canvas:
                Color:
                    rgba: .15, .15, .15, .9
                Rectangle:
                    size: self.size
                    pos: self.pos
            Button:
                size_hint: None, None
                width: 100
                height: 100
                on_press: print('This button does not overlap the menu above')

            # "ScrollViews containers"
            Custom
            Custom
            Custom
            Custom
            Custom
            Custom
    BoxLayout:  
        size_hint: 1, 0.05
        pos_hint: {'bottom':1.0}
        Button:
            on_press: print("This menu at the bottom is not affected by the problem that occurs with the top one")
    BoxLayout:
        size_hint: 1, 0.05
        pos_hint: {'top':1.0}
        Button:
            text: 'Fixed Menu'
            on_press: print('This button stops working if there is a horizontal scrollview "behind"')


<Custom@GridLayout>:
    cols: 1
#   id: streak_zone
    size_hint_y: None
    height: self.minimum_height
    row_force_default: True
    row_default_height: 60
    Label:
        id: label
        font_size: 20
        text: 'Teste'
        text_size: self.width, None
        size_hint_y: None
        
        halign: "center"
        valign: "middle"
        canvas:
            Color:
                rgba: (0, 1, 0, .5) # DarkOliveGreen
            Rectangle:
                size: self.size
                pos: self.pos

    StackLayout:
        id : grid
        size_hint_y: None
        
        ToggleButton:
            text:'1'
            size_hint:1/3, 1
            group:'ttt'
        ToggleButton:
            text:'2'
            size_hint:1/3, 1
            group:'ttt'
        ToggleButton:
            text:'3'
            size_hint:1/3, 1
            group:'ttt'
        ToggleButton:
            text:'4'
            size_hint:1/3, 1
            group:'ttt'
        ToggleButton:
            text:'5'
            size_hint:1/3, 1
            group:'ttt'
        ToggleButton:
            text:'6'
            size_hint:1/3, 1
            group:'ttt'
        ToggleButton:
            text:'7'
            size_hint:1/3, 1
            group:'ttt'
        ToggleButton:
            text:'8'
            size_hint:1/3, 1
            group:'ttt'
            

''' 


class ScrollApp(FloatLayout):
    pass


class Test(App):
    def build(self):
        kv1 =  Builder.load_string(kv)
        print("jhe ",kv1.height)
        return kv1
        return ScrollApp()

Test().run()

I am getting this layout after running it.

enter image description here

I have read many articles on GridLayout and ScrollView but still unable to fix this issue. What am I missing ?

Updated code:

from kivy.app import App
from kivy.lang.builder import Builder
from kivy.uix.floatlayout import FloatLayout
from  kivy.effects.scroll import ScrollEffect

kv = '''
#:import ScrollEffect kivy.effects.scroll.ScrollEffect
ScrollApp:

<ScrollApp>:
    ScrollView:
        size_hint: 1.0, 0.90
        pos_hint: {'center_y':0.5}
        padding: 22, 0, 22, 50
        spacing: 50
        effect_cls: ScrollEffect
        GridLayout:
            cols: 1
        #   id: streak_zone
            size_hint_y: None
            height: self.minimum_height
            #row_force_default: True
            #row_default_height: 400   
            canvas:
                Color:
                    rgba: .15, .15, .15, .9
                Rectangle:
                    size: self.size
                    pos: self.pos
            Button:
                size_hint: None, None
                width: 100
                height: 100
                on_press: print('This button does not overlap the menu above')

            # "ScrollViews containers"
            Custom
            Custom
            Custom
            Custom
            Custom
            Custom
    BoxLayout:  
        size_hint: 1, 0.05
        pos_hint: {'bottom':1.0}
        Button:
            on_press: print("This menu at the bottom is not affected by the problem that occurs with the top one")
    BoxLayout:
        size_hint: 1, 0.05
        pos_hint: {'top':1.0}
        Button:
            text: 'Fixed Menu'
            on_press: print('This button stops working if there is a horizontal scrollview "behind"')


<Custom@GridLayout>:
    cols: 1
#   id: streak_zone
    size_hint_y: None
    height: self.minimum_height
    #row_force_default: True
    #row_default_height: 60
    Label:
        id: label
        font_size: 20
        text: 'Teste'
        text_size: self.width, None
        size_hint_y: None
        
        halign: "center"
        valign: "middle"
        canvas:
            Color:
                rgba: (0, 1, 0, .5) # DarkOliveGreen
            Rectangle:
                size: self.size
                pos: self.pos

    StackLayout:
        id : grid
        size_hint_y: None
        
        ToggleButton:
            text:'1'
            size_hint:1/3, 1
            group:'ttt'
        ToggleButton:
            text:'2'
            size_hint:1/3, 1
            group:'ttt'
        ToggleButton:
            text:'3'
            size_hint:1/3, 1
            group:'ttt'
        ToggleButton:
            text:'4'
            size_hint:1/3, 1
            group:'ttt'
        ToggleButton:
            text:'5'
            size_hint:1/3, 1
            group:'ttt'
        ToggleButton:
            text:'6'
            size_hint:1/3, 1
            group:'ttt'
        ToggleButton:
            text:'7'
            size_hint:1/3, 1
            group:'ttt'
        ToggleButton:
            text:'8'
            size_hint:1/3, 1
            group:'ttt'
            

''' 


class ScrollApp(FloatLayout):
    pass


class Test(App):
    def build(self):
        kv1 =  Builder.load_string(kv)
        print("jhe ",kv1.height)
        return kv1
        return ScrollApp()

Test().run()

Solution

  • I think the problem is that whenever you use the minimum_height property of GridLayout, you must make sure that the size of its children are well defined, and you can't use size_hint_y for those children.

    So here is a slightly modified version of your kv that specifies more height properties:

    #:import ScrollEffect kivy.effects.scroll.ScrollEffect
    ScrollApp:
    
    <ScrollApp>:
        ScrollView:
            size_hint: 1.0, 0.90
            pos_hint: {'center_y':0.5}
            padding: 22, 0, 22, 50
            spacing: 50
            effect_cls: ScrollEffect
            GridLayout:
                cols: 1
            #   id: streak_zone
                size_hint_y: None
                height: self.minimum_height
                #row_force_default: True
                #row_default_height: 400   
                canvas:
                    Color:
                        rgba: .15, .15, .15, .9
                    Rectangle:
                        size: self.size
                        pos: self.pos
                Button:
                    size_hint: None, None
                    width: 100
                    height: 100
                    on_press: print('This button does not overlap the menu above')
    
                # "ScrollViews containers"
                Custom
                Custom
                Custom
                Custom
                Custom
                Custom
        BoxLayout:  
            size_hint: 1, 0.05
            pos_hint: {'bottom':1.0}
            Button:
                on_press: print("This menu at the bottom is not affected by the problem that occurs with the top one")
        BoxLayout:
            size_hint: 1, 0.05
            pos_hint: {'top':1.0}
            Button:
                text: 'Fixed Menu'
                on_press: print('This button stops working if there is a horizontal scrollview "behind"')
    
    
    <Custom@GridLayout>:
        cols: 1
    #   id: streak_zone
        size_hint_y: None
        height: self.minimum_height
        #row_force_default: True
        #row_default_height: 60
        Label:
            id: label
            font_size: 20
            text: 'Teste'
            text_size: self.width, None
            size_hint_y: None
            height: 50
    
            halign: "center"
            valign: "middle"
            canvas:
                Color:
                    rgba: (0, 1, 0, .5) # DarkOliveGreen
                Rectangle:
                    size: self.size
                    pos: self.pos
    
        StackLayout:
            id : grid
            size_hint_y: None
            height: self.minimum_height
    
            ToggleButton:
                text:'1'
                size_hint:1/3, None
                height: 50
                group:'ttt'
            ToggleButton:
                text:'2'
                size_hint:1/3, None
                height: 50
                group:'ttt'
            ToggleButton:
                text:'3'
                size_hint:1/3, None
                height: 50
                group:'ttt'
            ToggleButton:
                text:'4'
                size_hint:1/3, None
                height: 50
                group:'ttt'
            ToggleButton:
                text:'5'
                size_hint:1/3, None
                height: 50
                group:'ttt'
            ToggleButton:
                text:'6'
                size_hint:1/3, None
                height: 50
                group:'ttt'
            ToggleButton:
                text:'7'
                size_hint:1/3, None
                height: 50
                group:'ttt'
            ToggleButton:
                text:'8'
                size_hint:1/3, None
                height: 50
                group:'ttt'