Skip to content Skip to sidebar Skip to footer

Kivy Popup Running In Separate Thread

I am populating a treeview in Kivy that takes some time depending on how large it is. In the case the tree is large and takes awhile, I would like to display a popup while it is p

Solution 1:

I built an app which does something similar to what you're doing (different computation, but as you said the point was it was time-consuming and you want to thread a popup that shows the app isn't crashed - it's just crankin' the numbers). What ended up working for me was to set up a button to execute a dummy function which toggles both the popup and the calculation. Run the popup first and then thread the calculation through the 'from threading import Thread' module to execute the computation on a separate thread.

Here's a working example. It's just sleeping for 5 seconds but you can stick your computation into that function and it should work just fine. What it does is opens the popup before the computation and closes the popup when the calculation is done. Also, you can stick a 'Loading.gif' file into the folder and it'll import that as your loading gif if you want to use something other than what kivy pulls up (which is essentially a loading gif for loading your Loading.gif which isn't loading because it's not there... haha). Also added an 'ABORT' button if your user gets tired of waiting.

Finally just as a side note, I've had difficulties getting the .kv file to build into the pyinstaller application bundeler, so just as a heads up, using the builder.load_string(KV) function is a good alternative for that.

from threading import Thread
from sys import exit
from kivy.app import App
from kivy.uix.gridlayout import GridLayout
from kivy.uix.popup import Popup
from kivy.lang import Builder

KV = '''
<Pop>:
    id:pop
    title: ''
    auto_dismiss: False
    padding: 10
    spacing: 10

    BoxLayout:
        BoxLayout:
            padding: 10
            spacing: 10
            orientation: 'vertical'
            Label:
                font_size: 22
                size_hint_y: None
                text_size: self.width, None
                height: self.texture_size[1]
                text: "Process is currently running."
            Label:
                id: error_msg
                size_hint_x: 0.3
                text: ''

            BoxLayout:
                orientation: 'vertical'
                Button:
                    background_color: (1,0,0,1)
                    text: "ABORT"
                    on_press: root.sysex()

        AsyncImage:
            source: 'Loading.gif'

<MetaLevel>:
    rows: 1
    cols: 1
    Button:
        text: 'RUN'
        on_release: root.dummy()

'''

Builder.load_string(KV)

classMetaLevel(GridLayout):

    defdummy(self, *args):
        App.get_running_app().pop.open()
        Thread(target=self.calculate, args=(args,), daemon=True).start()

    defcalculate(self, *args):
        import time
        time.sleep(5)
        App.get_running_app().pop.dismiss()


classPop(Popup):
    defsysex(self):
        exit()


classCruncher(App):
    defbuild(self):
        self.pop = Pop()
        return MetaLevel()


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

Solution 2:

Were you able to get this sorted?

I think it works if you use the thread for populating the tree rather than using it for showing the popup. After populating the tree, in the same thread you can close the pop up using Popup.dismiss()

main.py file

from kivy.app import App
from kivy.uix.popup import Popup
from kivy.uix.label import Label
from kivy.uix.boxlayout import BoxLayout
import time, threading

classpopupTestApp(App):
    defwaitSec(self):
        time.sleep(5)
        self.p.dismiss()

    defpopUpFunc(self):
        self.p = Popup(title='Test Popup', content=Label(text='This is a test'), size_hint=(None,None), size=(400,400))
        self.p.open()
        popUpThread = threading.Thread(target=self.waitSec)
        popUpThread.start()

if __name__ == '__main__':
    popupTestApp().run()

popuptest.kv file

BoxLayout:BoxLayout:id:LeftPaneButton:id:MyButtontext:'Popitup!'on_release:app.popUpFunc()BoxLayout:id:RightPaneLabel:text:'Another Pane'

Take a look at the below link where this is explained well.

Building a simple progress bar or loading animation in Kivy

Post a Comment for "Kivy Popup Running In Separate Thread"