Widget hierarchy

18 views
Skip to first unread message

WS

unread,
2:36 PM (7 hours ago) 2:36 PM
to Kivy users support
how can I place the widgets in their parents while keeping their positions correct ?

json is attached


import json
from kivy.app import App
from kivy.uix.floatlayout import FloatLayout
from kivy.uix.button import Button
from kivy.graphics import Color, Rectangle

class ColoredFloatLayout(FloatLayout):
def __init__(self, color, **kwargs):
super().__init__(**kwargs)
with self.canvas.before:
Color(*color)
self.rect = Rectangle(size=self.size, pos=self.pos)
self.bind(size=self._update_rect, pos=self._update_rect)

def _update_rect(self, instance, value):
self.rect.pos = instance.pos
self.rect.size = instance.size

class DynamicLayoutApp(App):
def build(self):
# Load JSON and create widgets
json_data = self.load_json('test.json')
main_layout = self.create_widgets_from_json(json_data)
return main_layout

def load_json(self, filename):
with open(filename, 'r') as file:
return json.load(file)

def create_widgets_from_json(self, data):
widget_map = {}
color_map = {
'New Form': (1, 0, 0, 0.5),
'Panel1': (0, 1, 0, 0.5),
'Panel2': (0, 0, 1, 0.5)
}

# First, create all widgets
for item in data:
for widget_type, attributes in item.items():
widget = self.create_widget(widget_type, attributes, color_map.get(attributes['id'], (1, 1, 1, 0.5)))
widget_map[attributes['id']] = widget

# Then, organize the widget hierarchy
for item in data:
for widget_type, attributes in item.items():
parent_widget = widget_map[attributes['id']]
for child_id in attributes.get('children', []):
child_widget = widget_map[child_id]
parent_widget.add_widget(child_widget)

# Returns the main widget
return widget_map["New Form"]

def create_widget(self, widget_type, attributes, color):
if widget_type == 'FloatLayout':
widget = ColoredFloatLayout(color=color)
elif widget_type == 'Button':
widget = Button(text=attributes['text'])
else:
raise ValueError(f"Unknown widget type: {widget_type}")

# Sets common widget properties
widget.id = attributes['id']
widget.size = attributes['size']
widget.pos = attributes['pos']
widget.size_hint = (attributes['size_hint'][0], attributes['size_hint'][1])

return widget

if __name__ == '__main__':
DynamicLayoutApp().run()








test.json

ElliotG

unread,
7:00 PM (3 hours ago) 7:00 PM
to Kivy users support
What seems to be the problem?  The widgets all appear to be at the positions provided in the JSON.  A float layout will honor the pos of it's children.

I added the following method to the App class:
    def on_start(self):
        print(f'{self.root=}')
        for w in self.root.walk():
            print(f'{w} pos:{w.pos} children: {w.children} color: {w.color}')


It shows the widgets are located as defined in the JSON.  The output of the code:
<__main__.ColoredFloatLayout object at 0x000001FC7D2D6350> pos:[0, 20] children: [<__main__.ColoredFloatLayout object at 0x000001FC7D3C7A10>] color: [1, 0, 0, 0.5]
<__main__.ColoredFloatLayout object at 0x000001FC7D3C7A10> pos:[48.99999999999977, 91.33709817549766] children: [<__main__.ColoredFloatLayout object at 0x000001FC7D440600>] color: [0, 1, 0, 0.5]
<__main__.ColoredFloatLayout object at 0x000001FC7D440600> pos:[27.0, 314.99999999999955] children: [<kivy.uix.button.Button object at 0x000001FC7D441160>] color: [0, 0, 1, 0.5]
<kivy.uix.button.Button object at 0x000001FC7D441160> pos:[75.99999999999983, 89.99999999999994] children: [] color: [1, 1, 1, 1]
Message has been deleted

WS

unread,
9:30 PM (3 minutes ago) 9:30 PM
to Kivy users support
however, the widgets are not in the determined position in relation to the parent, it is outside the FloatLayout, in the json id="Panel2"
Reply all
Reply to author
Forward
0 new messages