I'm new to programming and playing with Kivy to learn. I came across something weird so have created this small example to demonstrate.
In my text.kv file I have this:
#:kivy 2.0.0
<smallLabel@Label>:
font_size: 40
<bigLabel@Label>:
font_size: 60
BoxLayout:
orientation:'vertical'
padding: 20
spacing: 5
smallLabel:
text: 'Stays the same'
bigLabel:
id: changes
text: 'changes'
And in my python file this:
from kivy.app import App
class TestApp(App):
pass
if __name__ == "__main__":
TestApp().run()
When I run it I get this:
File "/home/marty/Python/datatut/test.kv", line 15
text: 'Stays the same'
^
SyntaxError: invalid syntax
Now, if I change the case of my widget so the first letter is upper-case it works:
<SmallLabel@Label>:
font_size: 40
<bigLabel@Label>:
font_size: 60
BoxLayout:
orientation:'vertical'
padding: 20
spacing: 5
SmallLabel:
text: 'Stays the same'
bigLabel:
id: changes
text: 'changes'
Notice that I only changed the SmallLabel. I left the bigLable as lowercase. If I do this the other way around, that is leave smallLabel but make BigLabel It fails with same error. Why do I need to capitlise the name of my widget and why only the first one? I did notice in all of the examples that I've seen the first letter is always capitlised for the custom widget name but have not seen that this is a requirement, and if it is, then why does the second widget work if the first one is capitalised?
The KV lang loader needs to be able to distinguish between properties of your widget, and sub widgets, and as you can see both kind are simply a line of text ended by a :
, but there is a trick, by assuming that your classes follow PEP8 convention of Capitalized classes and snake_case attributes, it’s able to make the guess correctly.
This is (i agree a bit lightly) indicated in https://kivy.org/doc/stable/guide/lang.html#instantiate-children which states
Note
Widget names should start with upper case letters while property names should start with lower case ones. Following the PEP8 Naming Conventions is encouraged.
I assume the second one doesn’t need this guess, as it’s unindented after the first block, so it can’t be an attribute of the parent class (attributes must be before children declaration), so it can only be a child widget, and this rule is not needed in this situation, but i couldn’t find how this happen from a quick glance at the code