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

如何在Kivy中通过按钮点击跨类更新set_value变量?

解决Kivy中点击按钮更新进度条值的问题

你的问题核心有两个:一是set_value是普通类属性,Kivy无法监听它的变化来刷新界面;二是KomagomaApp的average方法没法直接获取到三个进度条的实例。下面是具体解决方案:

步骤说明

  • 将set_value改为Kivy的NumericProperty,这样值变化时会自动触发界面重绘
  • 在MainWidget的kv代码中给三个进度条添加id,方便后续获取实例
  • 修改average方法,通过App实例获取到MainWidget里的进度条实例,再更新它们的set_value

修改后的Python代码

from kivy.app import App
from kivy.uix.widget import Widget
from kivy.uix.anchorlayout import AnchorLayout
from kivy.properties import NumericProperty

class CircularProgressBarMath(AnchorLayout):
    set_value = NumericProperty(0)

class CircularProgressBarPhysic(AnchorLayout):
    set_value = NumericProperty(75)

class CircularProgressBarChemistry(AnchorLayout):
    set_value = NumericProperty(65)

class MainWidget(Widget):
    pass

class KomagomaApp(App):
    def build(self):
        return MainWidget()

    def average(self):
        # 获取MainWidget里的三个进度条实例
        math_bar = self.root.ids.math_bar
        physic_bar = self.root.ids.physic_bar
        chemistry_bar = self.root.ids.chemistry_bar
        
        # 这里可以替换成你实际的计算逻辑,示例是每个值加10
        math_bar.set_value += 10
        physic_bar.set_value += 10
        chemistry_bar.set_value += 10
        # 确保值不超过100(因为2.7*100=270,对应完整的圆弧)
        math_bar.set_value = min(math_bar.set_value, 100)
        physic_bar.set_value = min(physic_bar.set_value, 100)
        chemistry_bar.set_value = min(chemistry_bar.set_value, 100)

修改后的kv文件代码

<CircularProgressBarMath>:
    canvas.before:
        Color:
            rgb: (0.329, 0.298, 0.263)
        Line:
            width: 1.3
            ellipse: (self.x, self.y, self.width, self.height, 0, 270)

    canvas.after:
        Color:
            rgb: (0.827, 0.737, 0.557)
        Line:
            id: progress_bar_math
            width: 2.3
            ellipse: (self.x, self.y, self.width, self.height, 0, root.set_value*2.7)

<CircularProgressBarPhysic>:
    canvas.before:
        Color:
            rgb: (0.329, 0.298, 0.263)
        Line:
            width: 1.3
            ellipse: (self.x, self.y, self.width, self.height, 0, 270)

    canvas.after:
        Color:
            rgb: (0.827, 0.737, 0.557)
        Line:
            id: progress_bar_physic
            width: 2.3
            ellipse: (self.x, self.y, self.width, self.height, 0, root.set_value*2.7)

<CircularProgressBarChemistry>:
    canvas.before:
        Color:
            rgb: (0.329, 0.298, 0.263)
        Line:
            width: 1.3
            ellipse: (self.x, self.y, self.width, self.height, 0, 270)

    canvas.after:
        Color:
            rgb: (0.827, 0.737, 0.557)
        Line:
            id: progress_bar_chemistry
            width: 2.3
            ellipse: (self.x, self.y, self.width, self.height, 0, root.set_value*2.7)

<MainWidget>:
    BoxLayout:
        orientation: 'horizontal'
        size: root.width, root.height
        padding: 50

        BoxLayout:
            orientation: 'vertical'
            size_hint: 1, 1
            padding: 20

            AnchorLayout:
                anchor_x: 'center'
                size_hint: 1, 1

                Button:
                    text: '+'
                    font_size: '20px'
                    pos_hint: {'top': 0.1, 'right': 1}
                    size_hint: 0.1, 0.1
                    on_release: app.average()

                CircularProgressBarMath:
                    id: math_bar
                    size_hint: None, None
                    size: 500, 500
                    pos_hint: {'center_x': 0.5, 'center_y': 0.5}

                CircularProgressBarPhysic:
                    id: physic_bar
                    size_hint: None, None
                    size: 420, 420
                    pos_hint: {'center_x': 0.5, 'center_y': 0.5}

                CircularProgressBarChemistry:
                    id: chemistry_bar
                    size_hint: None, None
                    size: 340, 340
                    pos_hint: {'center_x': 0.5, 'center_y': 0.5}

说明

  • 给每个进度条类补全了canvas.before和canvas.after的绘制逻辑,确保三个进度条都能正常显示
  • average方法里的数值更新逻辑可以根据你的需求替换,示例是每次点击加10并限制最大值为100
  • 使用NumericProperty后,修改set_value会自动触发进度条的重绘,无需手动调用刷新方法

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.04 13:01:55