Welcome!
This is the community forum for my apps Pythonista and Editorial.
For individual support questions, you can also send an email. If you have a very short question or just want to say hello — I'm @olemoritz on Twitter.
Making a progress bar?
-
Context: I’m pretty experienced with Python, but new to Pythonista and iOS dev.
I have a SiriShortcut that needs a UI. It’s a yoga timer that takes a list off poses and times, and reads each pose and waits for the duration. I’d like to switch to using Pythonista in order to have the pose name visible.
I can make the basic UI and process the list, but I’m not sure how to make a visible progress bar. It seems like this should be a standard UI element but I’m not finding anything in the docs.
Can anyone give me a pointer? Thanks!
-
There is not a built in progress bar.
What you probably want to do is take a custom View class, with a custom draw() methos, which strokes a rect outline, then fills a narrower rect, based on a fractional width value. Or, draw N unfilled and M filled rectangles, etc. You would have a value property which when set, sets the internal attribute, then calls set_needs_display.
You could also install ui2 and use ProgressPathView. This allows any sort of path to be used as a progress bar.
Or, this a wrapper to the iOS objc UIProgressBar.
-
@chriscioffi I use two ui.Labels, one in the back with a text and a second one without text but with an half transparent background with the same height as the first label and with a width varying in function of the progress...
-
@chriscioffi other one like @jonb said, with only 2 pixels height
-
@chriscioffi, for a quick and dirty solution, use a disabled Slider as a progress bar.
There are also a couple of other recent threads for apps that might have relevant ”personal trainer” ideas.
-
Thanks all! I’ll figure something out when I have a little more spare time.
-
Here is a small snippet - far from comprehensive however it showcases using two views (one as container, one as the bar), with a label
# -*- coding: utf-8 -*- """ This was thrown together from various bits of unfinished code. I was planning on making it a lot better (working on a bunch of UI stuff, checkboxes, drop down, radio, etc) It works for my limited use case. """ import ui class ProgressBar(ui.View): def __init__(self, position=0, total=100, frame=(0,0, 250, 30)): self._position = position self.total = total self.frame = frame self.background_color = 'white' self.border_color = 'black' self.border_width = 0.5 self._label = None self._progressbar = ui.View( frame=self.frame, background_color = 'green', width = 0 ) self.label_properties = dict( flex = 'WH', alignment=ui.ALIGN_CENTER, frame = self.frame ) self.label = '0 %' self.add_subview(self._progressbar) self.add_subview(self._label) @property def label(self): return self._label @label.setter def label(self, value): assert isinstance(value, str), 'Use string value only' self.label_properties['text'] = value self._label = ui.Label(**self.label_properties) @property def position(self): return self._position @position.setter def position(self, value): if value > self.total: value = self.total self._position = value self._progressbar.width = ( self.percent_of( self.percent_is(value, self.total), self.width ) ) self._label.text = '{} %'.format( int(self.percent_is(value, self.total)) ) @staticmethod def percent_is(part, whole): return 100.0 * float(part)/float(whole) @staticmethod def percent_of(percent, whole): return (percent * whole) / 100.0 def set_percent(self, percent): self.position = self.percent_of(percent, self.total) def next(self): self.position += 1 def draw(self): pass if __name__ == '__main__': v = ui.View() v.background_color = 'white' x = ProgressBar() x.position = 90 x.flex = '' x.frame = (80, 100, 250,30) v.add_subview(x) v.present() import time for i in range(11): ui.delay(x.next, i)
-
Thanks, @reticulated ! That helped me understand what I was missing.
Mine is not at all generic, but it works.
C
-
Thought I'd share my "final" version:
It's not very sophisticated but I think it will work nicely for me. All documentation needed should be in the header comment.