Почему ключевое слово root обрабатывается по-разному, когда оно вызывается в Kivy? - PullRequest
0 голосов
/ 02 октября 2018

Как сделать круговой индикатор выполнения в киви?

Я нашел источник выше для кругового индикатора выполнения и заметил что-то странное.

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


class CircularProgressBar(ProgressBar):

    def __init__(self, **kwargs):
        super(CircularProgressBar, self).__init__(**kwargs)

        # Set constant for the bar thickness
        self.thickness = 40

        # Create a direct text representation
        self.label = CoreLabel(text="0%", font_size=self.thickness)

        # Initialise the texture_size variable
        self.texture_size = None

        # Refresh the text
        self.refresh_text()

        # Redraw on innit
        self.draw()

    def draw(self):

        with self.canvas:

            # Empty canvas instructions
            self.canvas.clear()

            # Draw no-progress circle
            Color(0.26, 0.26, 0.26)
            Ellipse(pos=self.pos, size=self.size)

            # Draw progress circle, small hack if there is no progress (angle_end = 0 results in full progress)
            Color(1, 0, 0)
            Ellipse(pos=self.pos, size=self.size,
                    angle_end=(0.001 if self.value_normalized == 0 else self.value_normalized*360))

            # Draw the inner circle (colour should be equal to the background)
            Color(0, 0, 0)
            Ellipse(pos=(self.pos[0] + self.thickness / 2, self.pos[1] + self.thickness / 2),
                    size=(self.size[0] - self.thickness, self.size[1] - self.thickness))

            # Center and draw the progress text
            Color(1, 1, 1, 1)
            Rectangle(texture=self.label.texture, size=self.texture_size,
                      pos=(self.size[0]/2 - self.texture_size[0]/2, self.size[1]/2 - self.texture_size[1]/2))

    def refresh_text(self):
        # Render the label
        self.label.refresh()

        # Set the texture size each refresh
        self.texture_size = list(self.label.texture.size)

    def set_value(self, value):
        # Update the progress bar value
        self.value = value

        # Update textual value and refresh the texture
        self.label.text = str(int(self.value_normalized*100)) + "%"
        self.refresh_text()

        # Draw all the elements
        self.draw()


class Main(App):

    def just_function(self):
        print(self.root) # <----- this will print None

    # Simple animation to show the circular progress bar in action
    def animate(self, dt):
        print(self.root) # <---- this prints CircularProgressBar object
        if self.root.value < 80:
            self.root.set_value(self.root.value + 1)
        else:
            self.root.set_value(0)

    # Simple layout for easy example
    def build(self):
        container = Builder.load_string(
            '''CircularProgressBar:
    size_hint: (None, None)
    height: 200
    width: 200
    max: 80''')

        # Animate the progress bar
        Clock.schedule_interval(self.animate, 0.1)
        print(self.root) # <---- this prints None
        self.just_function() # <---- this prints None
        return container


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

Когда вывзгляните на Main(App)

В этом источнике self.root здесь рассматривается как CircularProgressBar.

Но, когда я делаю print(self.root), он печатает None.

Он распознает CircularProgressBar, только когда self.root находится в функции, которая вызывается Clock.scheduled_interval(func, rate).

Кто-нибудь знает, что здесь происходит?

1 Ответ

0 голосов
/ 02 октября 2018

Объяснение очень простое и четко объяснено в документах :

root = нет

Возвращен корневой виджетс помощью метода build () или метода load_kv (), если файл kv содержит корневой виджет.

Из приведенного выше понятно, что root - это элемент, который возвращается вbuild() метод, поэтому, прежде чем что-то вернет эту функцию, root будет None, поэтому, когда вы печатаете self.root в build() или вызываете функцию, которая печатает self.root перед возвратом этой функции, вы всегда получите None.После возврата рута это будет то, что вы вернули, то есть container объект класса CircularProgressBar.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...