Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
328 views
in Technique[技术] by (71.8m points)

python - Kivy widgets underneath other widgets are interactable, how to prevent this?

Consider an app containing a button in a RelativeLayout. If any widget, aside from a button, is placed atop of it, thus hiding the button, this button and any other children to the RelativeLayout will be interactable even if it not visible.

What can be done to force this functionality?

Here is an example: notice how the button in the center of the app still receives touch events, despite being completely hidden:

from kivy.app import App
from kivy.uix.relativelayout import RelativeLayout
from kivy.uix.button import Button
from kivy.graphics import *
from kivy.core.window import Window
from kivy.uix.widget import Widget


class MyApp(App):
    def build(self):
        
        def btn_pressed(instance):
            print('ok')
        
        root = RelativeLayout()
        button = Button()
        root.add_widget(button)
        
        button.size_hint = (None, None)
        button.pos_hint = {'center_x': 0.5, 'center_y': 0.5}
        button.bind(on_press=btn_pressed)
        
        layout = RelativeLayout()
        with layout.canvas:
            Color(0,0,0,1)
            Rectangle(size=(Window.size[0], Window.size[1]))
        
        root.add_widget(layout)
        
        return root

MyApp().run() ```
question from:https://stackoverflow.com/questions/65600949/kivy-widgets-underneath-other-widgets-are-interactable-how-to-prevent-this

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

The default behavior for most widgets is to allow touch events to continue to be dispatched. This is controlled by the return value of the on_touch_XXX() methods. A True return means "do not continue dispatching" and a False return means "continue dispatching". So you can halt the dispatch of on_touch_down events by defining a custom class that stops the dispatching. For example:

class MyTouchBlocker(RelativeLayout):
    def on_touch_down(self, touch):
        if self.collide_point(*touch.pos):
            return True
        else:
            return super(MyTouchBlocker, self).on_touch_down(touch)

And in your code, you can replace:

layout = RelativeLayout()

with:

layout = MyTouchBlocker()

See the documentation.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

2.1m questions

2.1m answers

60 comments

57.0k users

...