How to make circular progress bar in kivy?
我在上面找到了圆形进度条的来源,并指出了一些奇怪的地方。
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)
。
有人知道这里发生了什么吗?
答案 0 :(得分:1)
解释非常简单,并且在docs中有清楚的解释:
根=无
由build()方法或load_kv()返回的根窗口小部件 如果kv文件包含根窗口小部件,则该方法。
从以上内容可以理解,root
是在build()
方法中返回的元素,因此在返回该函数之前,root
将是None
,因此,当您在self.root
中打印build()
或调用返回self.root
的函数,然后再返回该函数时,将始终得到None
。返回根之后,它将返回您返回的内容,即container
类CircularProgressBar
的对象。