I'm trying do dynamically build a Kivy layout with a vertical BoxLayout containing a varying number of custom MyRow
widgets that can change at runtime.
each row is an horizontal BoxLayout
I'm not using a GridLayout because MyRow
layout is being developed and can change in the near future adding widgets etc. like this example
But with the code below I only get small widgets stacked on top of each other in the bottom left corner of the window.
from kivy.app import App
from kivy.uix.widget import Widget
from kivy.uix.boxlayout import BoxLayout
from kivy.properties import StringProperty
class MyRow(Widget):
a = StringProperty('a')
b = StringProperty('b')
def __init__(self, **kwargs):
super(MyRow, self).__init__(**kwargs)
class MainScreen(Widget):
rows = [['a1','b1'],['a2','b2']] #example data
mainLayout = BoxLayout(orientation='vertical', spacing=5)
def __init__(self, **kwargs):
super(MainScreen, self).__init__(**kwargs)
self.add_widget(self.mainLayout)
for r in self.rows:
row_widget = MyRow()
row_widget.a = r[0]
row_widget.b = r[1]
self.mainLayout.add_widget(row_widget)
class MyApp(App):
def build(self):
return MainScreen()
if __name__ == '__main__':
MyApp().run()
and this is the kv file:
<MyRow>
BoxLayout:
orientation: "horizontal"
spacing: 30
Label:
id: a_label
text: root.a
Label:
id: b_label
text: root.b
In your sketch it says MyRow
is based on an horizontal BoxLayout. But it is not. It is build on widget
Simply changing
class MyRow(Widget):
to
class MyRow(BoxLayout):
will solve your problem.
To get spacing right or better I would update your code to the following
from kivy.app import App
from kivy.uix.widget import Widget
from kivy.uix.boxlayout import BoxLayout
from kivy.properties import StringProperty
from kivy.base import Builder
class MyRow(BoxLayout):
a = StringProperty('a')
b = StringProperty('b')
def __init__(self, **kwargs):
super(MyRow, self).__init__(**kwargs)
class MainScreen(BoxLayout):
rows = [['a1','b1'],['a2','b2']]*5
def __init__(self, **kwargs):
super(MainScreen, self).__init__(**kwargs)
self.orientation = "vertical"
for r in self.rows:
row_widget = MyRow()
row_widget.a = r[0]
row_widget.b = r[1]
self.add_widget(row_widget)
class MyApp(App):
def build(self):
return MainScreen()
if __name__ == '__main__':
MyApp().run()
and your kv
<MyRow>:
orientation: "horizontal"
spacing: 30
Label:
id: a_label
text: root.a
Label:
id: b_label
text: root.b
To inherit from a Boxlayot in python use class Row(BoxLayout):
in kv file use <Row@BoxLayout>: