Problem with Kivy - Scrollview overlapping with Box Layout above it

399 views
Skip to first unread message

Gustavo Sales

unread,
Aug 8, 2019, 4:59:52 PM8/8/19
to Kivy users support

I'm new with kivy and even programming and I'm creating an app with Python 3.7, and Kivy(1.11.1) that kinda looks like Netflix's Page layout, in which there is a menu fixed at the top and below it there is a vertical Scrollview with some horizontal scrollviews inside (just like the Netlix's catalogues, eg.: My List, Continue Watching, Series, etc). The problem is that when I scroll down the vertical ScrollView and one of the horizontal scrollview gets behind the fixed menu at the top, the events are sent to this horizontal scrollview and not to the fixed menu that is be above the Scrollview content. If I scroll the vertical Scrollview down and one of the horizontal scrollviews gets "behind" (in quotes because I imagine they aren't supposed to collide with each other) the menu at the top, if I click in the menu the event is being sent to the horizontal scrollview.


Image of what's happening https://imgur.com/a/rdbYV5a


from kivy.app import App
from kivy.lang.builder import Builder
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.scrollview import ScrollView

Builder.load_string(
'''
<ScrollApp>:
    orientation: 'vertical'
    BoxLayout:
        size_hint: 1, 0.12
        Button:
            text: 'Fixed Menu'
            on_press: print('This button stops working if there is a horizontal scrollview "behind"')

    ScrollView:
        bar_width: 10
        scroll_type: ['bars', 'content']
        BoxLayout:
            orientation: 'vertical'
            size_hint: 1, None
            height: self.minimum_height
            padding: 22, 0, 22, 50
            spacing: 50
            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
    BoxLayout:  
        size_hint: 1, 0.12
        Button:
            on_press: print("This menu at the bottom is not affected by the problem that occurs with the top one")


<Custom@BoxLayout>:
    orientation: 'vertical'
    size_hint: 1, None
    height: self.minimum_height
    Label:
        size_hint: None, None
        size: self.texture_size
        id: label
        font_size: 20
        text: 'Teste'
    ScrollView:
        do_scroll: True, True
        size_hint: 1, None
        height: 150
        GridLayout:
            id: grid
            size_hint: None, 1.01
            width: self.minimum_width
            spacing: 5
            cols: 3
            Button:
                size_hint: None, None
                size: 400, 150
                on_press: print('ScrollView button pressed')
            Button:
                size_hint: None, None
                size: 400, 150
                on_press: print('ScrollView button pressed')
            Button:
                size_hint: None, None
                size: 400, 150
                on_press: print('ScrollView button pressed')
''' )

class ScrollApp(BoxLayout):
    pass

class Test(App):
    def build(self):
        return ScrollApp()

Test().run()

Elliot Garbus

unread,
Aug 8, 2019, 10:50:20 PM8/8/19
to kivy-...@googlegroups.com

I can tell you why this is happening.  You will need go use the on_touch functions I shared previously to address this issue, or create a different layout.

 

Touch events are sent to every widget in the tree in reverse order.  The button on top of the window is the first widget in the tree, so the last one to receive a touch message.  When the scroll view and top button overlap, the scroll view widget is ‘catching’ the touch and claiming it, so it is not getting passed up the tree to the button on the top of the list.  This is also why the button on the bottom of the screen works as you would like it to.  It is the last button in the tree, so it is ‘catches’ the touch first.

 

An alternative idea:

You could try removing the top button from the top of the box layout, and put it in an achor layout in the bottom (but the top of the window) of the KV code, so that is earlier in the widget list.

--
You received this message because you are subscribed to the Google Groups "Kivy users support" group.
To unsubscribe from this group and stop receiving emails from it, send an email to kivy-users+...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/kivy-users/7f732324-e15f-4749-9d94-9ed2ff949a9e%40googlegroups.com.

 

Elliot Garbus

unread,
Aug 8, 2019, 11:12:24 PM8/8/19
to kivy-...@googlegroups.com
On second thought there must be a problem in the layout. The scrollview should be below the top button, not behind it. Explore the way these are sized.  I don’t have time now, but I may come back to this. 

Sent from my iPad

Elliot Garbus

unread,
Aug 10, 2019, 1:18:44 PM8/10/19
to Kivy users support
Setting the do-scroll properties appropriately, and putting the size of the grid back to 1, the buttons behave as expected. 
This brings back the requirement to manage the on_touch events for the horizontal scrollview.  
Code attached.
scrollss.py
Reply all
Reply to author
Forward
0 new messages