在画布中使用属性会导致TypeError:*:'int'和'NoneType'的不支持的操作数类型

时间:2016-09-06 07:21:29

标签: python kivy kivy-language

我正在尝试实现自己的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_ratio中的root.empty_ratiocanvas会使错误消失。因此,canvas出于某种原因将root.filled_ratio视为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

1 个答案:

答案 0 :(得分:0)

在使用kv语言之前简单地定义python中的属性可以解决问题:

class MyProgressBar(Widget):
    filled_ratio = NumericProperty(0)
    empty_ratio = NumericProperty(0)

(注意:我不认为这是一个完整的答案,因为它没有解释为什么这种情况发生。随意创建一个完全解决问题的答案)