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
.