当根小部件来自 .kv 文件的实例时,Kivy 出现错误
Arising errors in Kivy when root widget comes from an instance from .kv file
我有一个完美运行的简单代码,当我将 .kv 文件中的根 class 更改为根实例时,它停止工作(某些东西已经在工作)。
在 .kv 文件中已经有两行来测试两种情况之间的差异,这是注释一个/取消注释另一个的问题
我在 Kivy 论坛上问过,使用构建器 class 没有结果(因为我不明白区别在哪里!)。作为Kivy的新手,我现在的本能资源很少。
main.py:
from kivy.app import App
from kivy.uix.widget import Widget
from kivy.uix.button import Button
from kivy.properties import NumericProperty, ReferenceListProperty, ObjectProperty
from kivy.clock import Clock
from colorsys import hsv_to_rgb, rgb_to_hsv
from kivy.uix.gridlayout import GridLayout
class MoneyControl(Widget):
cartel = ObjectProperty(None)
lay = 3
rainbow = [0.0,1.0,1.0,1.0]
def hsva_to_rgba(self, hsva):
rgba = hsv_to_rgb(hsva[0], hsva[1], hsva[2])
rgba = list(rgba)
rgba.append(hsva[3])
return rgba
def update(self, dt):
self.lay += 1
self.cartel.text = str(self.lay)
self.rainbow[0] += self.lay*0.0001
finalRgba = self.hsva_to_rgba(self.rainbow)
self.cartel.color = finalRgba
class MoneyControlApp(App):
def build(self):
prog = MoneyControl()
Clock.schedule_interval(prog.update, 1.0 / 60.0)
return prog
if __name__ == '__main__':
MoneyControlApp().run()
kv 文件:
#:kivy 1.0.9
<MoneyControl@Widget>: #This works. Comment this line...
#MoneyControl:#RootWidget instance (as appears in documentation) # ...uncomment this one. It stops working.
cartel: crt
Label:
id: crt
font_size: 20
center_x: root.width * 0.5
top: root.height * 0.5
text: "hola"
color: 1, .3, .8, 1
预期的结果是在注释 .kv 文件的第一行并取消注释第二行之后示例继续运行。
实际结果是,如果您更改行,kivy 会出现关于 属性 的错误,这显然在第一种情况下有效(因此,没有错误)。
我想知道为什么会发生这种情况,当然还有如何修复它(只有在没有原因的情况下进行修复,才会导致 me/us 再次陷入同样的错误) .
kv
文件的两个版本之间的区别在于 <MoneyControl@Widget>:
是关于如何创建 MoneyControl
小部件的规则。虽然 MoneyControl:
实际上创建了一个 MoneyControl
小部件(您的代码会忽略它)。您需要将 MoneyControl:
更改为 <MoneyControl>:
以便比较规则。然后他们都工作了。
文档有点难以理解,但这里有一些要点:
在kv
文件中,<>
表示一条规则。所以 <MoneyControl>:
是一个规则,在 python 代码中任何 MoneyControl()
都将遵循该规则(包括在 build()
方法中)。
kv
文件中的 MoneyControl:
是构建 MoneyControl
小部件的一个实例的指令。它不是 rule
。如果它不是任何其他规则或小部件的子项,则它只是一个根小部件。
在 python 代码中(包括 build()
方法内部),MoneyControl()
将创建 MoneyControl
的实例。如果 kv
包含 MoneyControl
的 rule
,则在创建实例时将遵循该规则。如果没有 rule
,则创建 MoneyControl
的新实例而不考虑 kv
文件。
在您的 App
中,如果您有一个 build()
方法,那么无论该方法是什么 returns 都是您的应用程序 root
小部件。您可以在该方法中调用 MoneyControl()
,如果在加载的 kv
中有一个 rule
,则紧随其后的是 rule
。或者您可以 return kv
文件中的 root
小部件,如果您通过加载 kv
文件捕获 returned root
小部件(或字符串)。例如,theRoot = Builder.load_file('somefile.kv')
和 return theRoot
.
如果您的应用程序没有 build()
方法(或 build()
方法 returns None
),则从适当命名的 kv
文件将成为您的应用 root
小部件的代码。
我有一个完美运行的简单代码,当我将 .kv 文件中的根 class 更改为根实例时,它停止工作(某些东西已经在工作)。
在 .kv 文件中已经有两行来测试两种情况之间的差异,这是注释一个/取消注释另一个的问题
我在 Kivy 论坛上问过,使用构建器 class 没有结果(因为我不明白区别在哪里!)。作为Kivy的新手,我现在的本能资源很少。
main.py:
from kivy.app import App
from kivy.uix.widget import Widget
from kivy.uix.button import Button
from kivy.properties import NumericProperty, ReferenceListProperty, ObjectProperty
from kivy.clock import Clock
from colorsys import hsv_to_rgb, rgb_to_hsv
from kivy.uix.gridlayout import GridLayout
class MoneyControl(Widget):
cartel = ObjectProperty(None)
lay = 3
rainbow = [0.0,1.0,1.0,1.0]
def hsva_to_rgba(self, hsva):
rgba = hsv_to_rgb(hsva[0], hsva[1], hsva[2])
rgba = list(rgba)
rgba.append(hsva[3])
return rgba
def update(self, dt):
self.lay += 1
self.cartel.text = str(self.lay)
self.rainbow[0] += self.lay*0.0001
finalRgba = self.hsva_to_rgba(self.rainbow)
self.cartel.color = finalRgba
class MoneyControlApp(App):
def build(self):
prog = MoneyControl()
Clock.schedule_interval(prog.update, 1.0 / 60.0)
return prog
if __name__ == '__main__':
MoneyControlApp().run()
kv 文件:
#:kivy 1.0.9
<MoneyControl@Widget>: #This works. Comment this line...
#MoneyControl:#RootWidget instance (as appears in documentation) # ...uncomment this one. It stops working.
cartel: crt
Label:
id: crt
font_size: 20
center_x: root.width * 0.5
top: root.height * 0.5
text: "hola"
color: 1, .3, .8, 1
预期的结果是在注释 .kv 文件的第一行并取消注释第二行之后示例继续运行。
实际结果是,如果您更改行,kivy 会出现关于 属性 的错误,这显然在第一种情况下有效(因此,没有错误)。
我想知道为什么会发生这种情况,当然还有如何修复它(只有在没有原因的情况下进行修复,才会导致 me/us 再次陷入同样的错误) .
kv
文件的两个版本之间的区别在于 <MoneyControl@Widget>:
是关于如何创建 MoneyControl
小部件的规则。虽然 MoneyControl:
实际上创建了一个 MoneyControl
小部件(您的代码会忽略它)。您需要将 MoneyControl:
更改为 <MoneyControl>:
以便比较规则。然后他们都工作了。
文档有点难以理解,但这里有一些要点:
在kv
文件中,<>
表示一条规则。所以 <MoneyControl>:
是一个规则,在 python 代码中任何 MoneyControl()
都将遵循该规则(包括在 build()
方法中)。
kv
文件中的 MoneyControl:
是构建 MoneyControl
小部件的一个实例的指令。它不是 rule
。如果它不是任何其他规则或小部件的子项,则它只是一个根小部件。
在 python 代码中(包括 build()
方法内部),MoneyControl()
将创建 MoneyControl
的实例。如果 kv
包含 MoneyControl
的 rule
,则在创建实例时将遵循该规则。如果没有 rule
,则创建 MoneyControl
的新实例而不考虑 kv
文件。
在您的 App
中,如果您有一个 build()
方法,那么无论该方法是什么 returns 都是您的应用程序 root
小部件。您可以在该方法中调用 MoneyControl()
,如果在加载的 kv
中有一个 rule
,则紧随其后的是 rule
。或者您可以 return kv
文件中的 root
小部件,如果您通过加载 kv
文件捕获 returned root
小部件(或字符串)。例如,theRoot = Builder.load_file('somefile.kv')
和 return theRoot
.
如果您的应用程序没有 build()
方法(或 build()
方法 returns None
),则从适当命名的 kv
文件将成为您的应用 root
小部件的代码。