Reputation: 207
I am having issues getting Kivy to instantiate children Widgets. The issue here I believe is with how I am setting up the root widget. According to many examples I have seen including kivy's own documentation I should be able to instantiate children widgets to a root widget in the .kv file without using <> as such:
initApp.kv root_rule:
Root_Widget:
Test_Screen:
<Test_Screen>:
BoxLayout:
*there is stuff here, leaving blank to keep this question shorter*
Python File: (Note that the add_widget() is commented out)
class Test_Screen(Screen):
pass
class Root_Widget(ScreenManager):
def __init__(self, **kwargs):
super().__init__(**kwargs)
# self.add_widget(Test_Screen())
pass
class InitApp(App):
def build(self):
return Root_Widget()
if __name__ == '__main__':
InitApp().run()
However, this only leads to a blank app. There are two ways to fix this:
initApp.kv class_rule:
<Root_Widget>:
Test_Screen:
<Test_Screen>:
BoxLayout:
*there is stuff here, leaving blank to keep this question shorter*
Question
My question is, what is the difference here? Nesting Test_Screen underneath Root_Widget in the .kv file should be the exact same as calling the add_widget() method correct? Is this true and if so how/why is it different when setting Root_Widget as a class rule VS. a root rule?
Are there unforeseen consequences to saying that Root_Widget is a class rule rather than a root rule? It seems to work just fine using this approach but I don't know if it will cause other trouble as the app becomes more complex.
Upvotes: 1
Views: 381
Reputation: 16001
The blank window/app could be due to one of the following:
class InitApp(App):
then kv filename should be init.kv
. If you are not using Builder to load kv then the kv file name should be init.kv and not InitApp.kvkv filename - By name convention
By name convention
Kivy looks for a Kv file with the same name as your App class in lowercase, minus “App” if it ends with ‘App’ e.g:
MyApp -> my.kv
Instantiate and add a Label widget under Test_Screen as follow:
<Test_Screen>:
BoxLayout:
Label:
text: "kv file - Root Rule vs Class Rule"
what is the difference here? Nesting Test_Screen underneath Root_Widget in the kv file should be the exact same as calling the add_widget() method correct?
Yes it is the same.
add_widget(Test_Screen())
function to instantiate add children widgets under the parent. Test_Screen:
add_widget(Button())
to dynamically instantiate and add children widgets to a ScrollView.Is this true and if so how/why is it different when setting Root_Widget as a class rule VS. a root rule?
When the kv file is parsed, the root rule will be set as the root attribute of the App instance. Whereas a class rule, defines how any instance of that class will be graphically represented.
Are there unforeseen consequences to saying that Root_Widget is a class rule rather than a root rule?
I don't believe there is any unforeseen consequences. The only thing to note when using root rule or class rule in kv file are as follow.
If in your kv file, you have a root rule defined i.e. Root_Widget:
then in your Python code, you can do one of the following:
The kv file is init.kv
class InitApp(App):
pass
The kv file is not init.kv but InitApp.kv
class InitApp(App):
def build(self):
return Builder.load_file("InitApp.kv")
If in your kv file, you have a class rule defined i.e. <Root_Widget>:
then in your Python code, you can do one of the following:
The kv file is init.kv
class InitApp(App):
def build(self):
return Root_Widget()
The kv file is not init.kv but InitApp.kv
class InitApp(App):
def build(self):
Builder.load_file("InitApp.kv")
return Root_Widget()
Upvotes: 2