Home > Software design >  How can I center my GridLayout in the middle of the screen in Kivy?
How can I center my GridLayout in the middle of the screen in Kivy?

Time:02-05

I have a GridLayout with 8 cols, and I add 64 Buttons. (so 8x8). I want the Buttons to ALWAYS be quadratic, so I made that in my spot_init() function.

That all works great. When I make the Window smaller or bigger, the rest of my Screen gets black and the GridLayout stays in the Corner. But I wanted it to be centered.

For leftright that works perfectly fine but when i try applying that to updown as well, it does some weird things, I really cannot explain.

Some things I (maybe) found out:

  • When I do it exactly like right now, but in the code, the Y coord is 3 times as high as it should be for some reason.
  • When I then divide it by 3, it gets 7 times as high...
  • It doesn't change if I do it in .kv or in .py file
  • Moving GridLayout without RelativeLayout also doesn't work (almost the same thing happens)
  • Other askers seemed to have the same problem (or a similiar one) but their fixes didn't help me.

My .kv file:

RMainBoard:

<MainBoard>:
    cols:8
    # height: self.minimum_height
    # size_hint_y: None
    # size_hint_x: None

<RMainBoard@RelativeLayout>:
    pos:(self.width/2-min(self.width/8,self.height/8)*4,self.height/2-(min(self.width/8,self.height/8))*4)
    MainBoard:

My .py file:

#resize window (NEEDS TO BE AT VERY TOP)
from kivy.config import Config
Config.set('graphics', 'width', '600')
Config.set('graphics', 'height', '600')

from kivy.app import App
from kivy.core.window import Window
from kivy.uix.gridlayout import GridLayout
from kivy.uix.button import Button
from kivy.uix.label import Label
from kivy.metrics import dp
from kivy.properties import NumericProperty

class MainBoard(GridLayout):
    spots = []
    def __init__(self, **kwargs):
        super().__init__(**kwargs)
        self.spot_init()
        
    def on_size(self,*args):
        for spot in self.spots:
            spot_size = min(self.width/8,self.height/8)
            print(min(self.width/8,self.height/8))
            spot.height = spot_size
            spot.width = spot_size

    def spot_init(self):
        for i in range(0,64):
            self.spots.append(Button(size_hint=(None,None),height=self.height/8,width=self.width/8))
            self.add_widget(self.spots[i])

class TestApp(App):
    pass
TestApp().run()

Thanks a lot <3

CodePudding user response:

Rather than writing your own code to position the GridLayout, you can use the kv language to accomplish that. Here is a modified version of your code that does this:

# resize window (NEEDS TO BE AT VERY TOP)
from kivy.config import Config
from kivy.lang import Builder

Config.set('graphics', 'width', '600')
Config.set('graphics', 'height', '600')

from kivy.app import App
from kivy.uix.gridlayout import GridLayout
from kivy.uix.button import Button

kv = '''
RMainBoard:

<RMainBoard@RelativeLayout>:
    MainBoard:
        cols: 8
        size_hint: None, None
        
        # make MainBoard square
        width: min(root.width, root.height)
        height: self.width
        
        # position MainBoard in center of RMainBoard
        pos_hint: {'center_x': 0.5, 'center_y': 0.5}
    
<SquareButton>:
    size_hint: None, None
    
    # make the Button square
    width: min(self.parent.width/8, self.parent.height/8) if self.parent else 100
    height: self.width
'''


class SquareButton(Button):
    pass


class MainBoard(GridLayout):
    spots = []

    def __init__(self, **kwargs):
        super().__init__(**kwargs)
        self.spot_init()

    def spot_init(self):
        for i in range(0, 64):
            self.spots.append(SquareButton(text=str(i)))
            self.add_widget(self.spots[i])


class TestApp(App):
    def build(self):
        return Builder.load_string(kv)


TestApp().run()

Note that I included the kv as a string in the python code. That was just for my own convenience, and it could just as well be in your kv file.

I have defined a SquareButton class along with a <SquareButton> rule in the kv that keeps the SquareButton square. The Buttons created in the spot_init() method are now SquareButtons.

  • Related