Search code examples
python-3.xkivykivy-language

kivy button not perfect square when window is resized


I have created a ScrollView with a GridLayout that has a bunch of buttons. my issue is that I cant get the buttons to be a perfect square when changing the window size.

.py file:

from kivy.app import App

from kivy.uix.label import Label
from kivy.uix.button import Button
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.properties import ObjectProperty
from kivy.uix.scrollview import ScrollView

from kivy.uix.boxlayout import BoxLayout
from kivy.uix.stacklayout import StackLayout
from kivy.uix.floatlayout import FloatLayout
from kivy.uix.gridlayout import GridLayout


class LogInScreen(Screen):
    pass
class EmployeeScreen(Screen):
    pass
class MyLayout(GridLayout):
    def __init__(self,**kwargs):
        super(MyLayout,self).__init__(**kwargs)
        self.size_hint_y = (None)
        self.bind(minimum_height = self.setter('height'))



class Manager(ScreenManager):
    login_screen = ObjectProperty(None)
    employee_screen = ObjectProperty(None)


class CptApp(App):
    icon = 'Images\login\cptlogo.png'
    title = 'CPT'
    def build(self):
        return Manager()

if __name__=='__main__':
    CptApp().run()
enter code here

.kv file:

#: import Window kivy.core.window.Window
<Manager>:
id: screen_manager

login_screen: login_screen
employee_screen: employee_screen


LogInScreen:
    id: login_screen
    name: 'login'
    manager: screen_manager

    FloatLayout:
        StackLayout:
            orientation: 'lr-tb'
            canvas:
                Color:
                    rgba: 1,1,1,1
                Rectangle:
                    pos: self.pos
                    size: self.size
            Image:
                size_hint_y: .1
                source: 'Images\login\cptbanner.jpg'
                allow_stretch: True
                keep_ratio: True

            Image: 
                source: 'Images\login\HD7Brw.jpg'
                allow_stretch: True
                keep_ratio: False

    Label:
        size_hint_y: .05
        size_hint_x: .5
        pos_hint: {"x": .25, "y": .7}
        markup: True
        text: '[i][b][color=#000000]USER NAME[/color][/b][/i]'

    TextInput:
        id: 'username_input'
        multiline: False
        size_hint_x: .4
        size_hint_y: .05
        pos_hint: {"x": .3, "y": .65}

    Label:
        size_hint_y: .05
        size_hint_x: .5
        markup: True
        text: '[i][b][color=#000000]PASSWORD[/color][/b][/i]'
        pos_hint: {'x': .25, 'y': .5}

    TextInput:
        id: 'password_input'
        multiline: False
        password: True
        size_hint_x: .4
        size_hint_y: .05
        pos_hint: {'x': .3, 'y': .45}

    Image:
        source: 'Images/login/loginbutton.png'
        size_hint_x: .25
        size_hint_y: .1
        pos_hint: {'x': .375, 'y': .25}

    Button:
        id: 'login_button'
        background_color: 0,0,0,0
        markup: True
        text: '[i][b][color=#000000]LOGIN[/color][/b][/i]'
        size_hint_x: .25
        size_hint_y: .1
        pos_hint: {'x': .375, 'y': .25} 
        on_release: screen_manager.current = 'employeescreen'

EmployeeScreen:
    id: employee_screen
    name: 'employeescreen'
    manager: screen_manager

    StackLayout:
        orientation: 'lr-tb'
        canvas:
            Color:
                rgba: 1,1,1,1
            Rectangle:
                pos: self.pos
                size: self.size
        Image:
            size_hint_y: .1
            source: 'Images\login\cptbanner.jpg'
            allow_stretch: True
            keep_ratio: True

        ScrollView:
            size: (Window.width, Window.height)

            MyLayout:
                cols: 2                 
                height: self.minimum_height
                pos: root.pos

                Button:
                    height: 40
                    size_hint_y: None
                    text: 'TEST'
                Button:
                    height: 40
                    size_hint_y: None
                    text: 'TEST'
                Button:
                    height: 40
                    size_hint_y: None
                    text: 'TEST'
                Button:
                    height: 40
                    size_hint_y: None
                    text: 'TEST'
                Button:
                    height: 40
                    size_hint_y: None
                    text: 'TEST'
                Button:
                    height: 40
                    size_hint_y: None
                    text: 'TEST'
                Button:
                    height: 40
                    size_hint_y: None
                    text: 'TEST'
                Button:
                    height: 40
                    size_hint_y: None
                    text: 'TEST'
                Button:
                    height: 40
                    size_hint_y: None
                    text: 'TEST'
                Button:
                    height: 40
                    size_hint_y: None
                    text: 'TEST'
                Button:
                    height: 40
                    size_hint_y: None
                    text: 'TEST'    
                Button:
                    height: 40
                    size_hint_y: None
                    text: 'TEST'
                Button:
                    height: 40
                    size_hint_y: None
                    text: 'TEST'
                Button:
                    height: 40
                    size_hint_y: None
                    text: 'TEST'
                Button:
                    height: 40
                    size_hint_y: None
                    text: 'TEST'
                Button:
                    height: 40
                    size_hint_y: None
                    text: 'TEST'
                Button:
                    height: 40
                    size_hint_y: None
                    text: 'TEST'
                Button:
                    height: 40
                    size_hint_y: None
                    text: 'TEST'
                Button:
                    height: 40
                    size_hint_y: None
                    text: 'TEST'
                Button:
                    height: 40
                    size_hint_y: None
                    text: 'TEST'
                Button:
                    height: 40
                    size_hint_y: None
                    text: 'TEST'
                Button:
                    height: 40
                    size_hint_y: None
                    text: 'TEST'
                Button:
                    height: 40
                    size_hint_y: None
                    text: 'TEST'
                Button:
                    height: 40
                    size_hint_y: None
                    text: 'TEST'
                Button:
                    height: 40
                    size_hint_y: None
                    text: 'TEST'
                Button:
                    height: 40
                    size_hint_y: None
                    text: 'TEST'
                Button:
                    height: 40
                    size_hint_y: None
                    text: 'TEST'
                Button:
                    height: 40
                    size_hint_y: None
                    text: 'TEST'
                Button:
                    height: 40
                    size_hint_y: None
                    text: 'TEST'
                Button:
                    height: 40
                    size_hint_y: None
                    text: 'TEST'
                Button:
                    height: 40
                    size_hint_y: None
                    text: 'TEST'
                Button:
                    height: 40
                    size_hint_y: None
                    text: 'TEST'
                Button:
                    height: 40
                    size_hint_y: None
                    text: 'TEST'                    

enter code here

I want the height of the buttons to be the same as whatever the width is.


Solution

  • You can simply set the width to the same constant like so:

    Button:
       height: 40
       size_hint_y: None
       width: 40
       size_hint_x: None
       text: 'TEST'
    

    This produces perfect squares, but I guess this isn't what you want.

    this

    Another very simple thing is to set the button's height to be the same as it's width (literally):

    Button:
        size_hint_y: None
        height: self.width
        text: 'TEST'
    

    Which produces a nice result.

    result.

    And, when resized:

    resized

    Perfect squares still.