I'm clicking the button in the fixed menu at the top even though there is a Button in the vertical Scrollview, it doesn't effect the fixed menu.
I'm trying to click at the button in the fixed menu at the top but the actions are being sent to the horizontal Scrollview below.
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.
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()
You do manage to find obscure situations in kivy :-).
I believe the problem here is the order of touch event processing. The touch events are normally processed by the top level widgets, and they dispatch the event to their children, all the way down the
Widget
tree. In anyWidget
with multiple children, the touch event is dispatched to children in the reverse order that they have been add to their parent. And inkv
, childWidgets
are added in order as they appear (top to bottom). So, in your case, theScrollApp
has three children, and the touch events will be dispatched to its children starting with theBoxLayout
that contains the bottom menu, then to theScrollView
, and lastly, to theBoxLayout
that contains the top menu. So theScrollView
gets the touch event before the top menu, and dispatches the touch to its children (including theCustom
instances). So theButtons
in theCustom
see the touch event before the top menu sees it, and they claim it as their own. The obvious way to fix it would be to change the order ofWidgets
that appear in theScrollApp
, but sinceScrollApp
is aBoxLayout
, that would dramatically change how yourApp
looks. A different fix is to use aLayout
that doesn't depend on the order of its children. Something like aFloatLayout
has that characteristic. So, here is a modified version of your code, that makesScrollApp
extendFloatLayout
instead ofBoxLayout
:So, with this child order in
ScrollApp
, the top and bottom menus get their shot at the touch events before theScrollView
.I actually think your code should work without this change, so there may be something else happening that I couldn't find.