Search code examples
pythonkivykivy-languagekivymd

How to block touch functions in Kivy app temporarily?


I want to block the all the touch functions temporarily when some content is loading like, I have added an MDSpinner when its fetching some details from database and at that time, I don't want my users to type in the text fields or click the buttons on the screen. So, how can we do that?


Solution

  • You can do something like this

    from kivymd.app import MDApp
    
    from kivy.lang.builder import Builder
    from kivy.uix.modalview import ModalView
    from kivy.properties import BooleanProperty
    from kivy.clock import Clock
    
    KV = """
    <ModalViewSpinner>
        overlay_color: [0, 0, 0, 0.5]
        background_color: [0, 0, 0, 0]
        background: ''
        
        MDSpinner:
            size_hint: None, None
            size: dp(46), dp(46)
            pos_hint: {'center_x': .5, 'center_y': .5}
            active: root.active
            
    Screen:
        MDRoundFlatButton:
            text: "Fetching details from database"
            pos_hint: {"center_x": .5, "center_y": .5}
            on_release: app.block_screen()
    """
    
    
    class ModalViewSpinner(ModalView):
        active = BooleanProperty(False)
    
        def __init__(self, **kwargs):
            super().__init__(**kwargs)
            self.bind(on_open=lambda *args: self.change_spinner_state(True),
                      on_dismiss=lambda *args: self.change_spinner_state(False)
                      )
    
        def change_spinner_state(self, state: bool):
            self.active = state
    
    
    class TestApp(MDApp):
        def __init__(self, **kwargs):
            super().__init__(**kwargs)
            self.spinner_view = None
    
        def build(self):
            return Builder.load_string(KV)
    
        def block_screen(self):
            if not self.spinner_view:
                self.spinner_view = ModalViewSpinner()
    
            self.spinner_view.open()
    
            Clock.schedule_once(self.spinner_view.dismiss, 2.0)
    
    
    TestApp().run()