Construyendo una barra de progreso simple o cargando una animación en Kivy

Estoy escribiendo una IU de Kivy para la utilidad de línea cmd que he desarrollado. Todo funciona bien, pero algunos de los procesos pueden tardar desde unos pocos segundos hasta unos pocos minutos en procesarse y me gustaría proporcionar alguna indicación al usuario de que el proceso se está ejecutando. Idealmente, esto sería en forma de una rueda giratoria o una barra de carga o algo así, pero incluso si pudiera actualizar mi pantalla para mostrar al usuario que se está ejecutando un proceso, sería mejor que lo que tengo ahora.

Actualmente, el usuario presiona un botón en la interfaz de usuario principal. Esto abre una ventana emergente que verifica cierta información clave con el usuario, y si están contentos con esas opciones, presionan el botón “Ejecutar”. He intentado abrir una nueva ventana emergente para decirles que el proceso se está ejecutando, pero como la pantalla no se actualiza hasta que el proceso finaliza, esto no funciona.

Tengo una experiencia de encoding perdida, pero principalmente en el contexto de matemáticas e ingeniería, por lo que soy muy nuevo en el diseño de interfaces de usuario y tengo que manejar eventos y subprocesos. Un simple ejemplo autocontenido sería muy apreciado.

Hace poco abordé el problema que describiste: la display doesn't update until the process finishes

Aquí hay un ejemplo completo que obtuve trabajando con la ayuda de @andy_s en el canal IRC #Kivy:

Mi 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() 

Mi ejemplo.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() : pop_up_text: _pop_up_text size_hint: .5, .5 auto_dismiss: True title: 'Status' BoxLayout: orientation: "vertical" Label: id: _pop_up_text text: '' 

Si ejecuta este ejemplo, puede hacer clic en el botón Click Me , que debería abrir una “barra de progreso” en forma de una ventana emergente / modal. Esta ventana emergente permanecerá abierta durante 5 segundos sin bloquear la ventana principal. Después de 5 segundos, la ventana emergente se cerrará automáticamente.