Создание изображения прогресс-бара в Кивах - PullRequest
0 голосов
/ 04 октября 2018

Я пытаюсь создать индикатор выполнения, который работает с изображениями (пустое фоновое изображение индикатора выполнения и заполненное изображение)

Однако при попытке сделать это возникают 2 проблемы.

Вот мой код.

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 голосов
/ 04 октября 2018

Сделано несколько изменений, которые, я думаю, заставят его работать так, как вы и предполагали.Сначала избавился от звонка на 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()
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...