I have a simple code working perfectly, and when I change my root class in .kv file to a root instance, it stop working (something already was working).
In .kv file there are already two lines to test differences between two cases, is a matter of comment one / uncomment the other one
I've asked in Kivy forum, used builder class with no results (because I don't understand where is the difference!). As newbie in Kivy, I have very little instinctive resources right now.
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 file:
#: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
The expected results would be after comment the first line of .kv file and uncomment the second one the example keeps working.
The actual results is, if you change the line, kivy arises an error about a property that is clearly working in the first case (so, no error).
I would like to know why is happening this, and of course, how to fix it (Only the fix without the reason of why happens this, would lead me/us to fall again in the same error).
The difference between the two version of your kv
file is that <MoneyControl@Widget>:
is a rule for how to create a MoneyControl
widget. While MoneyControl:
actually creates a MoneyControl
widget (that is ignored by your code). You need to change MoneyControl:
to <MoneyControl>:
so that you are comparing rules. Then they both work.
The docs a bit difficult to understand, but here are some key points:
In the kv
file, <>
indicates a rule. So <MoneyControl>:
is a rule, and in the python code any MoneyControl()
will follow that rule (including in the build()
method).
A MoneyControl:
in the kv
file is instruction to build one instance of the MoneyControl
widget. It is not a rule
. It is only a root widget if it is not a child of any other rule or widget.
In the python code (including inside the build()
method), MoneyControl()
will create an instance of MoneyControl
. If the kv
included a rule
for MoneyControl
, then that rule will be followed in creating the instance. If there is no rule
, then a new instance of MoneyControl
is created without regard to the kv
file.
In your App
, if you have a build()
method, then whatever that method returns is your apps root
widget. You can call MoneyControl()
in that method, and if there is a rule
for it in the loaded kv
, then that rule
be followed. Or you can return the root
widget from the kv
file, if you captured the returned root
widget from loading the kv
file (or string). For example, theRoot = Builder.load_file('somefile.kv')
and return theRoot
.
If your app does not have a build()
method (or the build()
method returns None
), then a root widget from the appropriately named kv
file will becode your apps root
widget.