Search code examples
kivykivy-languagerotatetransform

Rotate 'complex' kivy widget inside a GridLayout


I'm currently coding an app with kivy (1.9.1) with is divided in 4 widgets thanks to a GridLayout (2 * 2). I search to have the two upper ones flipped by 180°.

I've tried to do it with a ScatterLayout, but the cells jumps to the bottom right... I've tried to insert the Scatter in a Widget, but I don't find how set the size correctly.

I read to use the following code in order to optimize ressources consumption:

        canvas.before:
            PushMatrix
            Rotate:
                angle: 180
                origin: self.center
        canvas.after:
            PopMatrix

It works at first glance, but the 'touching areas' have unfortunately not rotated.

The only two things I've found are to put the ScatterLayout inside and AnchorLayout or to use the previous code for each child...

I think there is a better solution but I've not been able to find it so far.

Please have a look at my .kv file below for a compilation of what I've experimented:

GridLayout:
    cols: 2
    rows: 2

    AnchorLayout:
        ScatterLayout:
            center: self.parent.center
            do_rotation: False
            do_translation: False
            do_scale: False
            rotation: 180

            GridLayout:
                cols: 2
                Button:
                    text: '1.1'
                Button
                    text: '1.2'

     Button:
         text: '2'

     GridLayout:
         size: self.parent.size
         center: self.parent.center
         cols: 3

         Button:
             canvas.before:
                 PushMatrix
                 Rotate:
                     angle: 180
                     origin: self.center
            canvas.after:
                PopMatrix
            text: '3.1'

         Button:
             canvas.before:
                 PushMatrix
                 Rotate:
                     angle: 180
                     origin: self.center
             canvas.after:
                  PopMatrix
             text: '3.2'

        GridLayout:
            size: self.parent.size
            center: self.parent.center
            rows: 2

            canvas.before:
                PushMatrix
                Rotate:
                    angle: 180
                    origin: self.center
            canvas.after:
                PopMatrix

            Button:
                text: '3.3.1'
            Button:
                text: '3.3.2'

    Button:
        text: '4'

The .py file is nothing more than that:

from kivy.app import App

class MainApp(App):
    pass

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

Thanks in advance.


Solution

  • Yes you can use scatter for this.
    Try this:

    from kivy.app import App
    from kivy.uix.gridlayout import GridLayout
    from kivy.lang import Builder
    
    
    KV = '''
    
    MyGrid:
        rows: 2
        cols: 2
        BoxLayout:
            id: w1
            Scatter:
                size: w1.size
                rotation: 180
                do_rotation: False
                Button:
                    size: w1.size
                    text: "Label1"
    
        BoxLayout:
            id: w2
            Scatter:
                size: w2.size
                rotation: 180
                do_rotation: False
                Button:
                    size: w2.size
                    text: "Label2"
    
        Button:
            text: "Label3"
        Button:
            text: "Label4"
    
    '''
    
    
    
    class MyGrid(GridLayout):
        pass
    
    
    class MyApp(App):
    
        def build(self):
            return Builder.load_string(KV)
    
    
    MyApp().run()