'how insert loading animation during a function in python kivy?

I'm a beginner and would like to insert an MDSpinner while executing a loop, or a mysql query, or some process that takes time. I made this example below to illustrate my problem:

from kivy.lang import Builder
from kivymd.app import MDApp
from kivy.clock import Clock
import threading


KV = '''
MDScreen:
    
    ScreenManager:
        id: screen_manager
    
        MDScreen:
            name: 'a'
            
            BoxLayout:
                orientation: 'vertical'
            
                MDLabel:
                    text: 'test - screen a'
                    pos_hint: {"center_x": .5, "center_y": .5}
                
                Button:
                    id: btn
                    text: 'screen a'
                    size_hint: 0.5, 0.1
                    pos_hint: {"center_x": .5, "center_y": .5}
                    on_press: 
                        load.active = True
                        app.aperta()
            
        MDScreen:
            name: 'b'
            
            BoxLayout:
                orientation: 'vertical'
            
                MDLabel:
                    text: 'test - screen b'
                    pos_hint: {"center_x": .5}
                
                Button:
                    id: btn2
                    text: 'screen b'
                    size_hint: 0.5, 0.5
                    pos_hint: {"center_x": .5, "center_y": .5}

    MDSpinner:
        id: load
        active: False
        size: dp(64), dp(64)
        size_hint: None, None
        pos_hint: {'center_x': 0.5, "center_y": .5}

'''


class Example(MDApp):
    def build(self):
        self.tela = Builder.load_string(KV)
        return self.tela

    def aperta(self):
        threading.Thread(target=self.op_1).start()

    def op_1(self, *args):

        cont = 0
        while cont < 1000000:
            cont += 1
            print(cont)

        self.tela.ids.load.active = False
        self.tela.ids.screen_manager.current = 'b'

Example().run()

however, when I change the screen, the following error appears and all the elements of the two screens overlap...

TypeError: Cannot change graphics instruction outside the main Kivy thread


Solution 1:[1]

You can also use the mainthread decorator, which is the equivalent to what @ApuCoder suggested:

class Example(MDApp):
    def build(self):
        self.tela = Builder.load_string(KV)
        return self.tela

    def aperta(self):
        threading.Thread(target=self.op_1).start()

    def op_1(self, *args):
        cont = 0
        while cont < 1000000:
            cont += 1
            print(cont)
        self.go_to_b()

    @mainthread
    def go_to_b(self):
        self.tela.ids.load.active = False
        self.tela.ids.screen_manager.current = 'b'

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 John Anderson