You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Kivy中实现圆形进度条?

Kivy圆形进度条实现方案

刚好我之前做过类似的Kivy圆形进度条,给你详细讲讲实现原理和完整代码!其实核心思路就是用Kivy的Canvas绘图系统,手动绘制两个圆弧(背景+前景),再叠加中间的进度文本,完全不需要依赖第三方库,自己就能定制出你想要的效果。

实现原理拆解

  • 自定义一个继承自Widget的进度条类,完全掌控绘图逻辑
  • 用Line(circle=...)绘制两个圆弧:一个灰色的背景完整圆弧,一个根据进度动态变化的彩色前景圆弧
  • 监听窗口大小变化,确保进度条始终居中且自适应尺寸
  • 绑定进度值的变化事件,实时更新圆弧角度和中间文本

完整代码示例

from kivy.app import App
from kivy.uix.widget import Widget
from kivy.properties import NumericProperty, StringProperty
from kivy.graphics import Color, Line
from kivy.core.text import Label as CoreLabel
from kivy.clock import Clock

class CircularProgressBar(Widget):
    # 定义进度属性,范围0-100,自动触发刷新
    progress = NumericProperty(0)
    # 中间显示的进度文本
    progress_text = StringProperty("0%")
    
    def __init__(self, **kwargs):
        super().__init__(**kwargs)
        # 配置圆弧参数,可根据需求调整
        self.line_width = 20  # 圆弧粗细
        self.start_angle = 90  # 进度条起始角度(90度对应顶部)
        self.total_angle = 360  # 完整圆周角度
        
        # 绑定进度变化到文本更新方法
        self.bind(progress=self._update_progress_content)

    def on_size(self, *args):
        # 窗口尺寸变化时,重新计算圆弧半径(保证居中且不超出边界)
        self.radius = min(self.width, self.height) / 2 - self.line_width
        self._update_canvas()

    def _update_progress_content(self, *args):
        # 更新中间显示的进度文本
        self.progress_text = f"{int(self.progress)}%"
        self._update_canvas()

    def _update_canvas(self):
        # 清空画布,重新绘制所有元素
        self.canvas.before.clear()
        self.canvas.after.clear()
        
        # 绘制背景圆弧(灰色)
        with self.canvas.before:
            Color(0.2, 0.2, 0.2, 1)  # RGB+透明度
            Line(
                circle=(self.center_x, self.center_y, self.radius, self.start_angle, self.start_angle + self.total_angle),
                width=self.line_width
            )
            
            # 绘制前景圆弧(蓝色,根据进度计算角度)
            progress_angle = (self.progress / 100) * self.total_angle
            Color(0.1, 0.5, 0.8, 1)
            Line(
                circle=(self.center_x, self.center_y, self.radius, self.start_angle, self.start_angle + progress_angle),
                width=self.line_width
            )
        
        # 绘制中间的进度文本
        text_label = CoreLabel(text=self.progress_text, font_size=40, color=(1, 1, 1, 1))
        text_label.refresh()
        text_texture = text_label.texture
        
        with self.canvas.after:
            Color(1, 1, 1, 1)
            self.canvas.after.add(text_texture)
            # 让文本居中显示
            text_texture.pos = (
                self.center_x - text_texture.width / 2,
                self.center_y - text_texture.height / 2
            )

class ProgressDemoApp(App):
    def build(self):
        progress_bar = CircularProgressBar()
        # 模拟进度动态变化(每秒增加5%,循环)
        def simulate_progress(dt):
            if progress_bar.progress < 100:
                progress_bar.progress += 5
            else:
                progress_bar.progress = 0
        Clock.schedule_interval(simulate_progress, 1)
        return progress_bar

if __name__ == "__main__":
    ProgressDemoApp().run()

自定义调整技巧

  • 修改颜色:更改Color()里的RGB值即可,比如把前景改成绿色Color(0.2, 0.8, 0.3, 1)
  • 调整圆弧粗细:修改self.line_width的值
  • 改变起始位置:把self.start_angle改成0(从右侧开始)、180(从底部开始)等
  • 文本样式:调整CoreLabel的font_size、font_name参数来修改字体大小和样式

运行代码后,你就能看到和示例图一致的圆形进度条,而且支持动态更新进度、窗口大小自适应~

内容的提问来源于stack exchange,提问作者Nandakishor Jahagirdar

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.29 07:00:38