0

I have asked a question about making a progress bar using stencilview here

And I could make one successfully.

Now I am trying to make a partially displaying image display as below

1im 2im

  1. First showing background image.
  2. Progressively display certain part of filled image.
  3. For example, fill up the arm then fill up the leg.
  4. In this case, I am trying to fill up depending on which arm and leg parameter is inserted.

I am thinking maybe I should device the images as 5 parts and have stencilview for each of them, but I am asking if there is a way of doing it without putting 5 different images and stencilviews.

Here is what I've currently done for a single progress image.

from kivy.app import App
from kivy.properties import StringProperty, NumericProperty
from kivy.uix.floatlayout import FloatLayout
from kivy.lang.builder import Builder
from kivy.clock import Clock


class CLS_PROGRESS_IMAGE(FloatLayout):
    background = StringProperty(None)
    progress_image = StringProperty(None)
    max = NumericProperty(0.0)

    def __init__(self, font_size=20, **kwargs):
        super(CLS_PROGRESS_IMAGE, self).__init__(**kwargs)
        self.progress_event = None
        self.font_size = font_size
        self.firstDraw = True
        self.pbi = None
        self.rect = None
        self.bgi = None
        self.value = 0.0
        self.value_normalized = 0.0

        self.horizontal = False
        self.looping = True

        self.progress_event = Clock.schedule_interval(self._progress, 0.1)

    def draw(self):
        if self.firstDraw:
            self.ids.bgi.source=self.background
            self.ids.pbi.source = self.progress_image
            self.ids.lab.font_size = self.font_size
            self.ids.lab.text = str(int(self.value_normalized*100)) + "%"
            self.ids.sten.pos = self.pos

            if self.horizontal is True:
                self.ids.sten.width = self.size[0]*self.value_normalized
                self.ids.sten.height = self.size[1]
            else:
                self.ids.sten.height= self.size[1]*self.value_normalized
                self.ids.sten.width = self.size[0]
            self.firstDraw = False
        else:
            self.ids.sten.pos = self.pos
            self.ids.lab.text = str(int(self.value_normalized*100)) + "%"
            if self.horizontal is True:
                self.ids.sten.width = self.size[0]*self.value_normalized
            else:
                self.ids.sten.height= self.size[1]*self.value_normalized

    def set_value(self, value):
        self.value = value
        self.value_normalized = self.value / self.max
        self.draw()

    def _progress(self, dt):
        if self.value < self.max - 1:
            self.set_value(self.value + 1)
        else:
            if self.looping:
                self.value = 0
                self.set_value(self.value)
            else:
                self.set_value(self.max)
                self.progress_event.cancel()


# Demo
class DemoApp(App):

    def build(self):
        kv = Builder.load_string('''
<CLS_PROGRESS_IMAGE>:
    Image:
        id: bgi
        allow_stretch: True
        keep_ratio: False
    StencilView:
        id: sten
        horizontal: False
        size_hint: (None, None)
        size: (0, root.height) if self.horizontal else (root.width, 0)
        Image:
            id: pbi
            allow_stretch: True
            keep_ratio: False
            size_hint: (None, None)
            size: (root.width, root.height)
            pos: (root.pos[0], root.pos[1])
    Label:
        id: lab
        text: '0%'
        size_hint: (None, None)
        size: self.texture_size
        pos_hint: {'center_x': 0.5, 'center_y': 0.5}

CLS_PROGRESS_IMAGE:
    size_hint: (None, None)
    height: 100
    width: 500
    max: 100
    background: '../images/empty.png'
    progress_image: '../images/filled.png'
    ''')
        return kv


if __name__ == '__main__':
    DemoApp().run()
BerryMan
  • 145
  • 1
  • 15

1 Answers1

0

Though this is not "partially" progressing an image,

but I could successfully emulate this by just using multiple different images.

Basically, what I've done was progressing images that look like they are partially loaded

and continue the same progressing until I use up all the images I put in a list.

class CLS_PROGRESS_BODY(CLS_PROGRESS_IMAGE):

    def __init__(self, **kwargs):
        super(CLS_PROGRESS_BODY, self).__init__(**kwargs)
        self.percentage_show = False
        self.image_list = None
        self.apply_adjustment = True
        self.progress_event.cancel()

        self.limitation = 0

    def start_progress(self):
        self.firstDraw = True
        self.progress_event.cancel()
        self.background= '../images/progress0.png'
        self.progress_image= '../images/progress1.png'
        self.image_list= ['../images/progress2.png', '../images/progress3.png', '../images/progress4.png',
                     '../images/progress5.png']
        if self.apply_adjustment:
            self.adjust_progress_position(self.progress_image)
        else:
            self.set_value(0)

        self.limitation = self.max * 0.8
        self.progress_event = Clock.schedule_interval(partial(self._progress, self.limitation), 0.1)

    def set_image_list(self, list_of_path):
        self.image_list = list_of_path

    def _progress(self, limit, dt):
        if self.value < self.max - 1 and self.value < limit:
            self.set_value(self.value + 1)
        else:
            self.set_value(self.max)
            self.progress_event.cancel()
            self.load_next_image()

    def load_next_image(self):
        if self.image_list:
            self.ids.bgi.source = self.ids.pbi.source
            self.ids.pbi.source = self.image_list.pop(0)
            if self.apply_adjustment:
                self.adjust_progress_position(self.ids.pbi.source)
            else:
                self.set_value(0)
            self.progress_event = Clock.schedule_interval(partial(self._progress, self.limitation), 0.1)
        else:
            if self.looping:
                self.start_progress()
BerryMan
  • 145
  • 1
  • 15