Ich dachte darüber nach, den Fortschritt der Funktion mit dem in Kivys Popup-Widget installierten Fortschrittsbalken-Widget anzuzeigen. Wenn Sie die Funktion verwenden, für die Sie den Fortschritt als Generator anzeigen möchten, sieht es so aus, als würde der Fortschrittsbalken innerhalb der Funktion aktualisiert.
Verwenden Sie das folgende Bild-Popup, das aus drei Teilen besteht: Fortschrittsbalken, Beschriftung und Schaltfläche.
Darüber hinaus wurden dem Popup-Widget die folgenden zwei Methoden hinzugefügt.
set_value ()
: Methode zum Aktualisieren des Werts und der Bezeichnung des Fortschrittsbalkensenable_close_button ()
: Methode zum Aktivieren der Schaltfläche zum Schließen des PopupsDer Code lautet wie folgt.
Class-PopupProgress
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.progressbar import ProgressBar
from kivy.uix.popup import Popup
from kivy.uix.button import Button
from kivy.uix.label import Label
class PopupProgress():
def __init__(self, value_init=0, value_max=1, title='', size=None,
auto_close=False):
self._auto_close = auto_close
self._box = BoxLayout(orientation='vertical')
if size is None:
size_hint = (1,1)
else:
size_hint = (None, None)
self.popup = Popup(title=title,
content=self._box,
auto_dismiss=False,
size_hint=size_hint,
size=tuple(size)
)
# progress bar
self._pb = ProgressBar(max=value_max, value=value_init)
self._box.add_widget(self._pb)
# label
self._label = Label(text='')
self._box.add_widget(self._label)
# close button
self._button = Button(text='Close', height=40, size_hint_y=None,
disabled=True)
self._button.bind(on_press=self.popup.dismiss)
self._box.add_widget(self._button)
self.popup.open() #Öffnen Sie ein Popup
def set_value(self, value=None, message=''):
if not value is None:
self._pb.value = value
self._label.text = message
if self._pb.value_normalized>=1:
if self._auto_close:
self.popup.dismiss()
else:
self.enable_close_button()
def enable_close_button(self):
self._button.disabled = False
Root Widget Zusätzlich zum Konstruktor (\ _ \ _ init \ _ \ _) zum Erstellen von Schaltflächen verfügt das Root-Widget über die folgenden drei Methoden.
func_test ()
: Methode (Generator), die den Fortschritt der zeitaufwändigen Verarbeitung überprüfen möchte
- Die Methode, die den Fortschritt der zeitaufwändigen Verarbeitung überprüfen möchte, ist ein Generator.
- Der Fortschritt und die Nachricht werden zurückgegeben, indem an der Stelle, an der Sie den Fortschritt des Prozesses überprüfen möchten, "Ertragswert, Nachricht" eingefügt wird.
- Am Ende des Prozesses wird "value = 1" zurückgegeben und die Schaltfläche "Schließen" aktiviert.
- Hier wird der Maximalwert = 1 des Fortschrittsbalkens gesetzt, aber jeder Wert kann mit
func_test_pp ()
gesetzt werden.- Hier wird "time.sleep (1)" eingestellt, um den zeitaufwändigen Prozess nachzuahmen.
func_test_pp ()
: Eine Methode zum Starten einer Schleife, die den Wert des Fortschrittsbalkens aktualisiert--Erstellen Sie eine Instanz der Popup-Widget-Klasse "self.pp". --Erstelle ein Iteratorobjekt
self.gen
aus dem obigenfunc_test ()
Generator.
- Verwenden Sie
Clock.schedule_once ()
, um die rekursive Methodepp_update ()
auszuführen, um die Schleife zu starten.
pp_update ()
: Rekursive Methode zum Aktualisieren des Werts des Fortschrittsbalkens
- Nachdem Sie das Iteratorobjekt
self.gen
einmal referenziert haben, aktualisieren Sie den Wert des Fortschrittsbalkens. --Verwenden SieClock.schedule_once ()
, um sich erneut aufzurufen, bis Sie eineStopIteration
oder einen anderen Fehler erhalten.- Wenn ein Fehler auftritt, ist die Schaltfläche im Popup aktiviert, damit der Benutzer das Popup schließen kann.
Class-RootWidget etc.
from kivy.app import App
from kivy.clock import Clock
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.button import Button
import time
class RootWidget(BoxLayout):
def __init__(self, **kwargs):
super(RootWidget, self).__init__(**kwargs)
button = Button(text='popup!')
button.bind(on_press=self.func_test_pp)
self.add_widget(button)
def pp_update(self, *args):
try:
value, message = next(self.gen)
self.pp.set_value(value, message)
Clock.schedule_once(self.pp_update, 0.1)
except StopIteration:
self.pp.enable_close_button()
except Exception as e:
self.pp.set_value(message=str(e))
self.pp.enable_close_button()
def func_test_pp(self, *args):
self.pp = PopupProgress(
title='TestPopupProgress',
size=(self.width/2, self.height/3)
)
self.gen = self.func_test()
Clock.schedule_once(self.pp_update, 0.1)
def func_test(self):
yield 0, 'Preparing...' #Verwenden Sie Yield, um den aktuellen Fortschritt und die Kommentare zurückzugeben (Anfang)
#Zeitaufwändige Verarbeitung, mit der Sie den Fortschritt überprüfen möchten
allitems = 5
for i in range(allitems):
time.sleep(1) #Etwas zeitaufwändiger Prozess
yield (i+1)/allitems, '{:d}/{:d}'.format(i+1, allitems) #Verwenden Sie Yield, um aktuelle Fortschritte und Kommentare zurückzugeben
yield 1, 'Complete.' #Verwenden Sie Yield, um den aktuellen Fortschritt und die Kommentare zurückzugeben (Ende)
class TestPopupProgressApp(App):
def build(self):
return RootWidget()
if __name__ == '__main__':
TestPopupProgressApp().run()
Das Obige kann wie folgt zusammengefasst werden.
test_popup_progress.py
from kivy.app import App
from kivy.clock import Clock
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.progressbar import ProgressBar
from kivy.uix.popup import Popup
from kivy.uix.button import Button
from kivy.uix.label import Label
import time
class PopupProgress():
def __init__(self, value_init=0, value_max=1, title='', size=None,
auto_close=False):
self._auto_close = auto_close
self._box = BoxLayout(orientation='vertical')
if size is None:
size_hint = (1,1)
else:
size_hint = (None, None)
self.popup = Popup(title=title,
content=self._box,
auto_dismiss=False,
size_hint=size_hint,
size=tuple(size)
)
# progress bar
self._pb = ProgressBar(max=value_max, value = value_init)
self._box.add_widget(self._pb)
# label
self._label = Label(text='')
self._box.add_widget(self._label)
# close button
self._button = Button(text='Close', height=40, size_hint_y=None,
disabled=True)
self._button.bind(on_press=self.popup.dismiss)
self._box.add_widget(self._button)
self.popup.open()
def set_value(self, value=None, message=''):
if not value is None:
self._pb.value = value
self._label.text = message
if self._pb.value_normalized>=1:
if self._auto_close:
self.popup.dismiss()
else:
self.enable_close_button()
def enable_close_button(self):
self._button.disabled = False
class RootWidget(BoxLayout):
def __init__(self, **kwargs):
super(RootWidget, self).__init__(**kwargs)
button = Button(text='popup!')
button.bind(on_press=self.func_test_pp)
self.add_widget(button)
def pp_update(self, *args):
try:
value, message = next(self.gen)
self.pp.set_value(value, message)
Clock.schedule_once(self.pp_update, 0.1)
except StopIteration:
self.pp.enable_close_button()
except Exception as e:
self.pp.set_value(message=str(e))
self.pp.enable_close_button()
def func_test_pp(self, *args):
self.pp = PopupProgress(
title='TestPopupProgress',
size=(self.width/2, self.height/3)
)
self.gen = self.func_test()
Clock.schedule_once(self.pp_update, 0.1)
def func_test(self):
yield 0, 'Preparing...'
allitems = 5
for i in range(allitems):
time.sleep(1)
yield (i+1)/allitems, '{:d}/{:d}'.format(i+1, allitems)
yield 1, 'Complete.'
class TestPopupProgressApp(App):
def build(self):
return RootWidget()
if __name__ == '__main__':
TestPopupProgressApp().run()
Recommended Posts