Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Building a simple progress bar or loading animation in Kivy?

I am writing a Kivy UI for cmd line utility I have developed. Everything works fine, but some of the processes can take from a few seconds to a few minutes to process and I would like to provide some indication to the user that the process is running. Ideally, this would be in the form of a spinning wheel or loading bar or something, but even if I could update my display to show the user that a process is running, it would be better than what I have now.

Currently, the user presses a button in the main UI. This brings up a popup that verifies some key information with the user, and if they are happy with those options, they press a 'run' button. I have tried opening a new popup to tell them that the process is running, but because the display doesn't update until the process finishes, this doesn't work.

I have a lot of coding experience, but mostly in the context of math and engineering, so I am very new to the designing of UIs and having to handle events and threads. A simple self-contained example would be greatly appreciated.

like image 892
David K Avatar asked Jun 02 '15 12:06

David K


People also ask

How can I make my KIVY app faster?

Load all your widgets at start One very simple method to improve performance of your app is to load all the heavy widgets or even all your apps widgets at the start of your application.

Is KIVY fast?

Kivy is very fast and efficient for a lot of things - in terms of basic graphics operations you can easily push and manipulate thousands of vertices with complex effects at no perceptible slowdown.

Does KIVY have a GUI?

Build and distribute beautiful Python cross-platform GUI apps with ease. Kivy runs on Android, iOS, Linux, macOS and Windows. Get started! Kivy has been built to be easy to use, cross-platform and fast.


1 Answers

I was recently tackling the problem you described: display doesn't update until the process finishes

Here is a complete example that I got working with the help of @andy_s in the #Kivy IRC channel:

My main.py:

from kivy.app import App
from kivy.uix.popup import Popup
from kivy.factory import Factory
from kivy.properties import ObjectProperty
from kivy.clock import Clock

import time, threading

class PopupBox(Popup):
    pop_up_text = ObjectProperty()
    def update_pop_up_text(self, p_message):
        self.pop_up_text.text = p_message

class ExampleApp(App):
    def show_popup(self):
        self.pop_up = Factory.PopupBox()
        self.pop_up.update_pop_up_text('Running some task...')
        self.pop_up.open()

    def process_button_click(self):
        # Open the pop up
        self.show_popup()

        # Call some method that may take a while to run.
        # I'm using a thread to simulate this
        mythread = threading.Thread(target=self.something_that_takes_5_seconds_to_run)
        mythread.start()

    def something_that_takes_5_seconds_to_run(self):
        thistime = time.time() 
        while thistime + 5 > time.time(): # 5 seconds
            time.sleep(1)

        # Once the long running task is done, close the pop up.
        self.pop_up.dismiss()

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

My example.kv:

AnchorLayout:
    anchor_x: 'center'
    anchor_y: 'center'
    Button:
        height: 40
        width: 100
        size_hint: (None, None)
        text: 'Click Me'
        on_press: app.process_button_click()

<PopupBox>:
    pop_up_text: _pop_up_text
    size_hint: .5, .5
    auto_dismiss: True
    title: 'Status'   

    BoxLayout:
        orientation: "vertical"
        Label:
            id: _pop_up_text
            text: ''

If you run this example, you can click the Click Me button, which should open up a "progress bar" in the form of a modal/pop-up. This pop up will remain open for 5 seconds without blocking the main window. After 5 seconds, the pop up will automatically be dismissed.

like image 124
Dirty Penguin Avatar answered Oct 17 '22 10:10

Dirty Penguin