Reputation: 3
I am trying to work on an Kivy application that displays certain data in the form of a Circular Progress Bar. I learnt about Circular Progress Bar through this link: How to make circular progress bar in kivy? However, I am unable to add this widget onto a particular screen.
I wish to embed the widget onto my screen and include a few other widgets. I have tried making a separate .kv file but it didn't work either. Here is my code. I wish to have the Circular Progress Bar inside my HomePage.
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
from kivy.uix.screenmanager import Screen, ScreenManager
Builder.load_string('''
<HomePage>:
FloatLayout:
canvas.before:
Rectangle:
# self here refers to the widget i.e BoxLayout
pos: self.pos
size: self.size
CircularProgressBar:
size_hint:(None,None)
height:400
width:400
max:80
''')
class HomePage(Screen):
pass
class CircularProgressBar(ProgressBar):
def __init__(self,**kwargs):
super(CircularProgressBar,self).__init__(**kwargs)
self.thickness = 40
self.label = CoreLabel(text="0",font_size=self.thickness)
self.texture_size= None
self.refresh_text()
self.draw()
def draw(self):
with self.canvas:
self.canvas.clear()
#No progress
Color(0.26,0.26,0.26)
Ellipse(pos=self.pos, size=self.size)
#Progress Circle
Color(1,0,0)
Ellipse(pos=self.pos,size=self.size,angle_end=0.5*360)#will be replaced with necessary data
#Inner Circle
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))
#Inner 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))
self.label.text = str(int(0.5*100))
def refresh_text(self):
self.label.refresh()
self.texture_size=list(self.label.texture.size)
def set_value(self, value):
self.value = value
self.label.text = str(int(0.5*100))
self.refresh_text()
self.draw()
sm = ScreenManager()
sm.add_widget(HomePage(name="HomePage"))
class HealthTrackingSystem(App):
def animate(self,dt):
if self.root.value<80:
self.root.set_value(self.root.set_value+1)
else:
self.root.set_value(0)
def build(self):
Clock.schedule_interval(self.animate, 0.1)
return sm
if __name__ == '__main__':
HealthTrackingSystem().run()
I am encountering the following error on running my code:
File "HealthTrackingSystem.py", line 70, in animate
if self.root.value<80
'ScreenManager' object has no attribute 'value'
Upvotes: 0
Views: 672
Reputation: 38857
In your code, self.root
is the ScreenManager
that you returned in your build
method. You may want to add an id
to your CircularProgressBar:
(in the kv
), and then use that to reference your CircularProgressBar
.
Here is what it would look like (including edits to get the CircularProgressBar
to work):
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
from kivy.uix.screenmanager import Screen, ScreenManager
Builder.load_string('''
<HomePage>:
FloatLayout:
canvas.before:
Rectangle:
# self here refers to the widget i.e BoxLayout
pos: self.pos
size: self.size
CircularProgressBar:
id: cp
size_hint:(None,None)
height:400
width:400
max:80
''')
class HomePage(Screen):
pass
class CircularProgressBar(ProgressBar):
def __init__(self,**kwargs):
super(CircularProgressBar,self).__init__(**kwargs)
self.thickness = 40
self.label = CoreLabel(text="0",font_size=self.thickness)
self.texture_size= None
self.refresh_text()
self.draw()
def draw(self):
with self.canvas:
self.canvas.clear()
#No progress
Color(0.26,0.26,0.26)
Ellipse(pos=self.pos, size=self.size)
#Progress Circle
Color(1,0,0)
Ellipse(pos=self.pos,size=self.size,angle_end=(self.value/100.0)*360)#will be replaced with necessary data
#Inner Circle
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))
#Inner 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))
self.label.text = str(int(self.value))
def refresh_text(self):
self.label.refresh()
self.texture_size=list(self.label.texture.size)
def set_value(self, value):
self.value = value
self.label.text = str(int(self.value))
self.refresh_text()
self.draw()
sm = ScreenManager()
sm.add_widget(HomePage(name="HomePage"))
class HealthTrackingSystem(App):
def animate(self,dt):
circProgressBar = self.root.get_screen('HomePage').ids.cp
if circProgressBar.value<80:
circProgressBar.set_value(circProgressBar.value+1)
else:
circProgressBar.set_value(0)
def build(self):
Clock.schedule_interval(self.animate, 0.1)
return sm
if __name__ == '__main__':
HealthTrackingSystem().run()
Upvotes: 1