1

独自の ProgressBar* ウィジェットを実装しようとしています。

from kivy.app import App
from kivy.uix.boxlayout import BoxLayout
from kivy.lang import Builder

kv = """
<MyProgressBar@Widget>:
    max: 1
    value: 0
    limited_value: min(self.value, self.max)
    # Filled ratio should never be 0 or 1
    # otherwise it would cause size_hints equal to 0,
    # that is, None-type value, resulting in ignoring size_hint
    filled_ratio: max(.00001, min(.9999, float(self.value) / self.max))
    empty_ratio: 1-self.filled_ratio
    filled_color: 0,1,0,1
    empty_color: .6,.6,.6,.4

    size_hint_y: .5
    pos_hint: {'center_x': .5, 'center_y': .5}
    canvas.before:
        Color:
            rgba: root.filled_color
        Rectangle:
            size: root.width * root.filled_ratio, root.height
            pos: root.pos
        Color:
            rgba: root.empty_color
        Rectangle:
            size: root.width * root.empty_ratio, root.height
            pos: root.x + root.width*root.filled_ratio, root.y

<MainWidget>:
    MyProgressBar

"""
Builder.load_string(kv)

class MainWidget(BoxLayout):
    pass

class MySimpleApp(App):
    def build(self):
        main = MainWidget(orientation='vertical')
        return main

if __name__ == '__main__':
    MySimpleApp().run()

コードを実行すると、次のエラーが表示されます。

 BuilderException: Parser: File "<inline>", line 20:
 ...
      18:            rgba: root.filled_color
      19:        Rectangle:
 >>   20:            size: root.width * root.filled_ratio, root.height
      21:            pos: root.pos
      22:        Color:
 ...
 TypeError: unsupported operand type(s) for *: 'int' and 'NoneType'

root.filled_ratioroot.empty_ratioincanvasを floatに置き換えると、エラーが消えます。したがって、canvasフロートである必要があるのに、何らかの理由でroot.filled_ratioasが表示されます。None

エラーは、代わりに次の場合にも消えます。

filled_ratio: max(.00001, min(.9999, float(self.value) / self.max))
empty_ratio: 1-self.filled_ratio

.. 私が使う:

filled_ratio: .4
empty_ratio: .6

私は何を間違っていますか?

* KivyにはすでにProgressBarがあります。

4

1 に答える 1