python - Why is 'root' keyword treated differently when it is called in Kivy?
问题描述
How to make circular progress bar in kivy?
I have found a source above for circular progress bar and noted something weird.
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()
When you take a look at Main(App)
In this source, self.root
is considered as CircularProgressBar
in here.
But, when I do print(self.root)
it prints None
.
It only recognize CircularProgressBar
when self.root
is in a function that is called by Clock.scheduled_interval(func, rate)
.
Does anyone know what is happening in here?
解决方案
解释很简单,在文档中有清楚的解释:
根 = 无
如果 kv 文件包含根小部件,则由 build() 方法或 load_kv() 方法返回的根小部件。
从上面可以理解, theroot
是build()
方法中返回的元素,因此在返回该函数之前root
将是None
,因此当您在其中打印self.root
或build()
调用self.root
在返回该函数之前打印的函数时,您将始终得到None
。返回根之后,它将是您返回的内容,即container
class 的对象CircularProgressBar
。
推荐阅读
- javascript - 如何从其他(blazor)库而不是自身引用 js/css 文件?
- c# - 卡住生成 + 将 .xlsx 文件从 ASP.NET Web API 后端发送到 Vue.js 前端
- python - 如何从 HTML 代码中的特定名称获取“href”值
- python - 如何检查 HTML 中的哪一行触发错误?
- scala - 在 spark scala 中将字符串拆分为单词
- sql - 在 SQL 中使用子字符串连接表
- sql - 运行 case 语句时出现转换失败错误
- c# - Android base64 图像到 .Net web api PNG 和 JPEG
- c++ - Mbient Lab Sensor API C++ 帮助:Visual Studio 2019 的未声明标识符?
- python - 获取错误“_io.TextIOWrapper”对象没有属性“ascii_lower”