在Kivy中,如何在具有多个屏幕的应用程序中的特定屏幕上添加CircularProgressBar?

时间:2019-02-10 09:53:09

标签: kivy kivy-language

我正在尝试使用Kivy应用程序,该应用程序以“循环进度条”的形式显示某些数据。我通过以下链接了解了通告进度栏:How to make circular progress bar in kivy? 但是,我无法将此小部件添加到特定屏幕上。

我希望将小部件嵌入到我的屏幕上,并包括其他一些小部件。我曾尝试制作一个单独的.kv文件,但它也不起作用。这是我的代码。我希望主页上有“循环进度栏”。

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()

我在运行代码时遇到以下错误:

 File "HealthTrackingSystem.py", line 70, in animate
 if self.root.value<80
 'ScreenManager' object has no attribute 'value'

1 个答案:

答案 0 :(得分:0)

在您的代码中,self.root是您在ScreenManager方法中返回的build。您可能想将id添加到CircularProgressBar:(在kv中),然后使用它来引用您的CircularProgressBar

这是它的样子(包括使CircularProgressBar生效的编辑):

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()