'Cannot create graphics instruction outside the main Kivy thread

I'm trying to create a small GUI with kivy. by clicking on the button named button it should launch the popup on another thread with a progress bar that evolves after 3 seconds. But kivy gives me an error saying "Cannot create graphics instruction outside the main Kivy thread" how to solve this problem?

 from kivy.app import App 
 from kivy.uix.label import Label
 from kivy.uix.progressbar import ProgressBar
 from kivy.uix.boxlayout import BoxLayout
 from kivy.uix.button import Button
 from kivy.uix.popup import Popup
 from kivy.lang import Builder

 import time
 import threading

 Builder.load_string(""" 

 <Interface>:

     orientation: 'vertical'
     Label:
       text: "Test"

  BoxLayout:
      orientation: 'vertical'
      Label
        text: "phone Number"

      TextInput:
          id: variable
          hint_text: ""
      Thebutton:
          user_input: variable.text
          text: "Buttion"
          on_release: self.do_action()

""")


class Interface(BoxLayout):
    pass


class Thebutton(Button):

    def bar_de_progress(self):
        bdp = ProgressBar()
        poo = Popup(title="Brute Forcing ...", content=bdp, size_hint=(0.5, 0.2))
        poo.open()
        time.sleep(1)
        bdp.value = 25

    def do_action(self, *args):
        threading.Thread(target=self.bar_de_progress).start()
        return


 class MyApp(App, Thebutton):

      def build(self):
          return Interface()


  if __name__ == "__main__":
      MyApp().run()


Solution 1:[1]

I cannot replicate your error, but the general rule is don't do GUI operations on threads other than the main thread. Here is a modified version of your Thebutton class that does that:

class Thebutton(Button):

    def bar_de_progress(self):
        # this is run on the main thread
        self.bdp = ProgressBar()
        poo = Popup(title="Brute Forcing ...", content=self.bdp, size_hint=(0.5, 0.2))
        poo.open()
        threading.Thread(target=self.update_progress).start()

    def update_progress(self):
        # this is run on another thread
        time.sleep(1)
        self.bdp.value = 25

    def do_action(self, *args):
        self.bar_de_progress()

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