在Kivy中制作图像进度条

时间:2018-10-04 02:34:31

标签: python kivy

我正在尝试制作一个适用于图像的进度条(空的背景进度条图像和填充的图像)

但是,当我尝试这样做时有两个问题。

这是我的代码。

from kivy.app import App
from kivy.uix.progressbar import ProgressBar
from kivy.uix.image import Image
from kivy.core.text import Label as CoreLabel
from kivy.graphics import Color, Rectangle
from kivy.lang.builder import Builder
from kivy.clock import Clock

class CLS_PROGRESS_BAR(ProgressBar):

    def __init__(self, background=None, progress_image=None, font_size=20, **kwargs):
        super(CLS_PROGRESS_BAR, self).__init__(**kwargs)
        self.background = background
        self.progress_image = progress_image
        self.progress_event = None
        self.font_size= font_size
        self.label = CoreLabel(text="0%", font_size=self.font_size)
        self.texture_size = None

        self.refresh_text()
        self.draw()

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

    def draw(self):
        with self.canvas:
            self.canvas.clear()
            # Background
            Image(source=self.background, pos=self.pos, size=self.size)

            # Draw Progress bar
            Image(source=self.progress_image,pos=self.pos,
                  size=(0.001 if self.value_normalized==0 else self.size[0]*self.value_normalized, self.size[1]),
                  )

            # Percentage text
            Color(1, 1, 1, 1)
            Rectangle(texture=self.label.texture, size=self.texture_size,
                      pos=(self.pos[0] + self.size[0] / 2 - self.texture_size[0] / 2,
                           self.pos[1] + self.size[1] / 2 - self.texture_size[1] / 2))

    def refresh_text(self):
        self.label.refresh()
        self.texture_size = list(self.label.texture.size)

    def set_value(self, value):
        self.value = value

        self.label.text = str(int(self.value_normalized*100)) + "%"
        self.refresh_text()
        # update
        self.draw()

    def progress(self, rate=0.1):
        self.progress_event = Clock.schedule_interval(self._progress, rate)

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


# Demo
class Main(App):

    def build(self):
        container = Builder.load_string(
            '''CLS_PROGRESS_BAR:
    size_hint: (None, None)
    height: 100
    width: 500
    max: 100
    background: 'empty.png'
    progress_image: 'filled.png'
    ''')

        return container


if __name__ == '__main__':
    Main().run()

第一个问题是,在更新过程时,它随机地从某个地方显示一个白色矩形。当我移除Image(source=self.background, pos=self.pos, size=self.size)时,该白色矩形不会出现,但是由于它是必不可少的,我仍然无法弄清楚该怎么办。

第二个问题是,当进度条向右伸展时,它的高度也会增加。

size=(0.001 if self.value_normalized==0 else self.size[0]*self.value_normalized, self.size[1])

如上所述,我将size[1]设置为固定的self.size[1]。但是,进度条的高度一直在增长。 (即使我输入了100这样的静态数字)

我现在不知道该怎么办。请给我一个主意。

1 个答案:

答案 0 :(得分:0)

做了一些我认为使其可以按预期工作的更改。首先摆脱了self.draw()中对__init__()的调用。由于ProgressBar大小当时无法使用,因此无法正常工作。接下来,我更改了draw()方法,使其仅创建所需的Widgets一次,然后在每次调用时对其进行更新。另外,删除未使用的progress()方法。我将allow_stretch=True, keep_ratio=False属性添加到进度条图像中。

from kivy.app import App
from kivy.uix.progressbar import ProgressBar
from kivy.uix.image import Image
from kivy.core.text import Label as CoreLabel
from kivy.graphics import Color, Rectangle
from kivy.lang.builder import Builder
from kivy.clock import Clock

class CLS_PROGRESS_BAR(ProgressBar):

    def __init__(self, background=None, progress_image=None, font_size=20, **kwargs):
        super(CLS_PROGRESS_BAR, self).__init__(**kwargs)
        self.background = background
        self.progress_image = progress_image
        self.progress_event = None
        self.font_size= font_size
        self.label = CoreLabel(text="0%", font_size=self.font_size)
        self.texture_size = None
        self.firstDraw = True
        self.pbi = None
        self.rect = None

        self.refresh_text()
        #self.draw()

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

    def draw(self):
        with self.canvas:
            if self.firstDraw:
                # Background
                Image(source=self.background, pos=self.pos, size=self.size)
                # Draw Progress bar
                self.pbi = Image(source=self.progress_image, pos=(self.pos[0], self.pos[1] + (self.size[1] - self.texture_size[1])/2.0),
                      allow_stretch=True, keep_ratio=False,
                      size=(0.001 if self.value_normalized==0 else self.size[0]*self.value_normalized, self.texture_size[1]))
                # Percentage text
                Color(1, 1, 1, 1)
                self.rect = Rectangle(texture=self.label.texture, size=self.texture_size,
                          pos=(self.pos[0] + self.size[0] / 2 - self.texture_size[0] / 2,
                               self.pos[1] + self.size[1] / 2 - self.texture_size[1] / 2))
                self.firstDraw = False
            else:
                self.pbi.width = self.size[0]*self.value_normalized
                self.rect.texture = self.label.texture
                self.rect.size = self.label.texture.size


    def refresh_text(self):
        self.label.refresh()
        self.texture_size = list(self.label.texture.size)

    def set_value(self, value):
        self.value = value

        self.label.text = str(int(self.value_normalized*100)) + "%"
        self.refresh_text()
        # update
        self.draw()

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


# Demo
class Main(App):

    def build(self):
        container = Builder.load_string(
            '''CLS_PROGRESS_BAR:
    size_hint: (None, None)
    height: 100
    width: 500
    max: 100
    background: 'empty.png'
    progress_image: 'filled.png'
    ''')

        return container


if __name__ == '__main__':
    Main().run()