I would like to create some kind of dynamic tile layout where the widgets would have an adjustable size (such as Appy Geek, which is like Flipboard but with resizable tiles).
I've been using this class, which is a bit dirty (with all the Clock.Schedule_once, but I couldn't make it work otherwise).
My problem is that I can't get this class to work dynamically. For example, using a simple main.py :
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from kivy.app import App
from kivy.uix.button import Button
class MainApp(App):
def add(self, gd, x, y, w, h):
print gd, x.text, y.text, w.text, h.text
x = int(x.text)
y = int(y.text)
w = int(w.text)
h = int(h.text)
gd.set_widget(Button(text='B %i %i' % (x, y)), x, y, w, h)
gd.do_layout()
MainApp().run()
and a simple .kv :
#:kivy 1.8.0
#:import SGridLayout SGridLayout
#:import SGridLayoutCell SGridLayout
BoxLayout:
orientation: 'vertical'
SGridLayout:
cols: 5
rows: 4
id: gd
BoxLayout:
orientation: 'horizontal'
size_hint_y: None
height: '50dp'
TextInput:
text: '1'
id: x
TextInput:
text: '1'
id: y
TextInput:
text: '1'
id: w
TextInput:
text: '1'
id: h
Button:
text: 'Add'
on_press: app.add(gd, x, y, w, h)
Button:
text: 'Remove'
When adding a button, it appears on the bottom left, even though we've chosen another pos with the input. But as soon as we resize the window, the button goes to its real pos.
Example : When adding a 1x1 button at the pos (1,1), and then resizing the window a little bit (Imgur album)
So... Any ideas ? TYA :)
Okay, I looked through your code and noticed that the widget's pos and size attributes are only updated when its respective cell's attributes are updated. I modified the SGridLayoutCell's add_widget method, as following, to make it work:
def add_widget(self, widget, row=0, col=0, width=1, height=1):
self.swidth = width
self.sheight = height
self.row = row
self.col = col
self.widget = widget
# They are updated now!
widget.pos = self.pos
widget.size = self.size
self.bind(pos=widget.setter('pos'))
if self.swidth == 1:
self.bind(width=widget.setter('width'))
else:
widget.width = self.width * self.swidth
if self.sheight == 1:
self.bind(height=widget.setter('height'))
else:
widget.height = self.height * self.sheight
Clock.schedule_once(self.post_init)