如何在kivy中制作圆形进度条?
Posted
技术标签:
【中文标题】如何在kivy中制作圆形进度条?【英文标题】:How to make circular progress bar in kivy? 【发布时间】:2018-11-05 16:04:11 【问题描述】:我想用 kivy 和 python 制作一个简单的圆形进度条。我搜索了在线文档和 GitHub 曲目,但没有找到解释循环进度条概念的正确示例。
如下图所示。我想发展。请任何人帮助我解决这个问题。
【问题讨论】:
我已经改进了我的最后一个答案以添加文本和更简单的可用性,希望这会有所帮助。 【参考方案1】:新的更好的版本
这篇文章受到的关注比我预期的要多,因此我决定花一点精力来创建这个小部件的升级版本。现在可以在GitHub 上找到它。这是一个可以用它做什么的示例(进度条实际上是透明的,我在 gif 中添加了黑色背景以使所有内容都可见):
如果有人感兴趣,我将保留旧帖子以供参考。
旧帖
我制作了一个小部件来代表您想要实现的目标。但是,确切地说,有一些限制:
您需要调用set_value
方法,而不仅仅是使用.value
设置进度条值。我非常不确定应该做些什么来实现与原始 ProgressBar
类中相同的行为;
你必须指定大小才能实现圆形,因为对象本身就是一个椭圆。
这里是代码,还有示例用法:
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)
#added pos[0]and pos[1] for centralizing label text whenever pos_hint is set
Rectangle(texture=self.label.texture, size=self.texture_size,
pos=(self.size[0] / 2 - self.texture_size[0] / 2 + self.pos[0], self.size[1] / 2 - self.texture_size[1] / 2 + self.pos[1]))
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):
# Simple animation to show the circular progress bar in action
def animate(self, dt):
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)
return container
if __name__ == '__main__':
Main().run()
输出:
【讨论】:
如果可能的话,你会建议我如何为上面的单个 python 文件为 kivy 和 python 制作单独的文件。不改变功能 是否可以手动设置圆形进度条的值而不是自更新,例如在kivy字符串中定义滑块并对应滑块的值,圆形进度条必须移动并更改圆形进度条内的文本。 您可以像使用ProgressBar
一样使用我的小部件,但您必须在想要设置一个时调用 set_value(value) (查看我提供的示例)。这将自动更新循环和文本进程。关于分离,只需创建一个新模块将类放在那里并将其导入到您想使用的任何地方。据我所知,要在您的 .kv 布局中使用它,您还必须将它与您的主 App 类一起导入模块中。尝试一下,看看你能用它做什么!
@NandakishorJahagirdar - 如果您仍然对使用它感兴趣,请查看更新版本的小部件。也许它会被证明更有用!以上是关于如何在kivy中制作圆形进度条?的主要内容,如果未能解决你的问题,请参考以下文章