如何在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
相关产品推荐
相关产品推荐

