Changing layout depending on window size

375 views
Skip to first unread message

Nick C

unread,
Mar 28, 2015, 3:19:57 PM3/28/15
to kivy-...@googlegroups.com
Hi, I'm trying to write an app that changes its layout depending on the orientation, or screen size; I've tried to make an example below where 3 buttons are laid out in one way or another, depending on if the screen is wide or tall.  However, the below gives me an error, and complains that the buttons already have a parent widget.  Why?  I never call add_widget(butx) in the constructor of AdaptWidget...
More importantly, how _should_ I accomplish this layout adaptability in kivy?
Thanks!


from kivy.app import App
from kivy.uix.widget import Widget
from kivy.uix.button import Button
from kivy.uix.boxlayout import BoxLayout

class AdaptWidget(BoxLayout):
    def __init__(self, **kw):
        super(AdaptWidget, self).__init__(**kw)
        self.but1 = Button(text='but1')
        self.but2 = Button(text='but2')
        self.but3 = Button(text='but3')
        self.layout = None

    def on_size(self, *args):
        self.clear_widgets()

        if self.size[0] > self.size[1]:
            self.layout = BoxLayout(orientation='horizontal')
            self.but1.size_hint = 0.7, 1

            self.layout.add_widget(self.but1)
            vert = BoxLayout(orientation='vertical')
            self.layout.add_widget(vert)
            self.but2.size_hint = (1,0.5)
            self.but3.size_hint = (1,0.5)
            vert.add_widget(self.but2)
            vert.add_widget(self.but3)
        else:
            self.layout = BoxLayout(orientation='vertical')
            self.but1.size_hint = 1, 0.7
            self.layout.add_widget(self.but1)
            horiz = BoxLayout(oreintation='horizontal')
            self.layout.add_widget(horiz)
            self.but2.size_hint = 0.5, 1
            self.but3.size_hint = 0.5, 1
            horiz.add_widget(self.but2)
            horiz.add_widget(self.but3)

        self.add_widget(self.layout)

class TestLayoutApp(App):
    def build(self):
        return AdaptWidget()

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

ZenCODE

unread,
Mar 28, 2015, 6:49:56 PM3/28/15
to kivy-...@googlegroups.com
Without looking to deep into what you're trying to do, this fixes it. The error is pretty clear: the buttons are already in a layout, so adding them to a new one is not allowed. They can only be in one widget tree at a time (for hopefully obvious reasons).


from kivy.app import App
from kivy.uix.widget import Widget
from kivy.uix.button import Button
from kivy.uix.boxlayout import BoxLayout

class AdaptWidget(BoxLayout):
   
def __init__(self, **kw):
       
super(AdaptWidget, self).__init__(**kw)
       
self.but1 = Button(text='but1')
       
self.but2 = Button(text='but2')
       
self.but3 = Button(text='but3')
       
self.layout = None

   
def on_size(self, *args):
       
self.clear_widgets()

       
if self.size[0] > self.size[1]:

           
for button in [self.but1, self.but2, self.but3]:
               
if button.parent:
                    button
.parent.remove_widget(button)


           
self.layout = BoxLayout(orientation='horizontal')
           
self.but1.size_hint = 0.7, 1

           
self.layout.add_widget(self.but1)
            vert
= BoxLayout(orientation='vertical')
           
self.layout.add_widget(vert)
           
self.but2.size_hint = (1,0.5)
           
self.but3.size_hint = (1,0.5)
            vert
.add_widget(self.but2)
            vert
.add_widget(self.but3)
       
else:

           
for button in [self.bu1, self.but2, self.but3]:
               
if button.parent:
                    button
.parent.remove_widget(button)


           
self.layout = BoxLayout(orientation='horizontal')
           
self.but1.size_hint = 0.7, 1


           
self.layout = BoxLayout(orientation='vertical')

ZenCODE

unread,
Mar 28, 2015, 6:52:30 PM3/28/15
to kivy-...@googlegroups.com
# More efficiently
from
kivy.app import App

from kivy.uix.widget import Widget
from kivy.uix.button import Button
from kivy.uix.boxlayout import BoxLayout

class AdaptWidget(BoxLayout):
   
def __init__(self, **kw):
       
super(AdaptWidget, self).__init__(**kw)
       
self.but1 = Button(text='but1')
       
self.but2 = Button(text='but2')
       
self.but3 = Button(text='but3')
       
self.layout = None

   
def on_size(self, *args):
       
self.clear_widgets()

        for button in [self.but1, self.but2, self.but3]:
            if b
utton.parent:
                button
.parent.remove_widget(button)
        if self.size[0] > self.size[1]:

Federico Curzel

unread,
Mar 28, 2015, 7:33:06 PM3/28/15
to kivy-...@googlegroups.com
Is StackLayout responsive?

--
You received this message because you are subscribed to the Google Groups "Kivy users support" group.
To unsubscribe from this group and stop receiving emails from it, send an email to kivy-users+...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

ZenCODE

unread,
Mar 29, 2015, 5:23:42 AM3/29/15
to kivy-...@googlegroups.com
@Frederico

They are all responsive in a sense, being event driven. What exactly do you mean by responsive?

Federico Curzel

unread,
Mar 29, 2015, 6:43:50 AM3/29/15
to kivy-...@googlegroups.com
I mean the fact that widgets are "stacked" in automatic, as would happen in a web page..
Like bootstrap grids, for example :
http://getbootstrap.com/examples/grid/


Il giorno dom 29 mar 2015 alle ore 11:23 ZenCODE <zenkey....@gmail.com> ha scritto:
@Frederico

They are all responsive in a sense, being event driven. What exactly do you mean by responsive?

--

ZenCODE

unread,
Mar 30, 2015, 2:33:45 AM3/30/15
to kivy-...@googlegroups.com
Okay, then yes. You just add widgets, and it stacks them according to it's size at that point in time.
Reply all
Reply to author
Forward
0 new messages