How do I control initial Size and positioning of labels and buttons in a splitter in Kivy?

Viewed 60

It's me again, trying to understand Kivy concepts.

I have a widget with a base class of RelativeLayout containing a chessboard image displaying in a splitter. I want to display a label, and 2 buttons horizontally below the chessboard spaced a small distance away from the chessboard and still have everything resizable with splitter. I've tried numerous ways to no avail. What I currently have is this:

Current GUI

What I want is this: (How do I achieve it?)

Desired GUI

Here is the code:

import kivy
from kivy.app import App
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.button import Button
from kivy.uix.label import Label
from kivy.uix.relativelayout import RelativeLayout
from kivy.uix.splitter import Splitter
from kivy.uix.image import Image

kivy.require('2.0.0')

class ChessBoardWidget(RelativeLayout):  # FloatLayout
    def __init__(self, **kwargs):
        super(ChessBoardWidget, self).__init__(**kwargs)

        repertoire_boxlayout = BoxLayout(orientation='horizontal')
        repertoire_boxlayout.add_widget(Label(text='Repertoire for:'))
        repertoire_boxlayout.add_widget(Button(text='White'))
        repertoire_boxlayout.add_widget(Button(text='Black'))

        chessboard_gui_boxlayout = BoxLayout(orientation='vertical')
        chessboard_gui_boxlayout.add_widget(
            Image(source="./data/images/chess-pieces/DarkerGreenGreyChessBoard.png", pos=self.pos,
                  size_hint=(1, 1), keep_ratio=True, allow_stretch=True))
        chessboard_gui_boxlayout.add_widget(repertoire_boxlayout)
        self.add_widget(chessboard_gui_boxlayout)

class SplitterGui(BoxLayout):
    def __init__(self, **kwargs):
        super(SplitterGui, self).__init__(**kwargs)
        self.orientation = 'horizontal'

        # Splitter 1
        split1_boxlayout = BoxLayout(orientation='vertical')
        split1 = Splitter(sizable_from='bottom', min_size=74, max_size=1100)

        chessboard_widget = ChessBoardWidget()  

        split1.add_widget(chessboard_widget) 
        split1_boxlayout.add_widget(split1)
        s3_button = Button(text='s3', size_hint=(1, 1))
        split1_boxlayout.add_widget(s3_button)
        self.add_widget(split1_boxlayout)

        # Splitter 2
        split2 = Splitter(sizable_from='left', min_size=74, max_size=1800)
        s2_button = Button(text='s2', size_hint=(.1, 1))
        split2.add_widget(s2_button)
        self.add_widget(split2)


class ChessBoxApp(App):
    def build(self):
        return SplitterGui()  # root


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

1 Answers

In a BoxLayout (see the documentation), you can use size_hint and size (or height, width) to adjust sizes. So, you can set the height of your Buttons, and let the Image use the remaining height of the BoxLayout:

class ChessBoardWidget(RelativeLayout):
    def __init__(self, **kwargs):
        super(ChessBoardWidget, self).__init__(**kwargs)

        repertoire_boxlayout = BoxLayout(orientation='horizontal', size_hint=(1, None), height=30)  # set height of Buttons
        repertoire_boxlayout.add_widget(Label(text='Repertoire for:'))
        repertoire_boxlayout.add_widget(Button(text='White'))
        repertoire_boxlayout.add_widget(Button(text='Black'))

        chessboard_gui_boxlayout = BoxLayout(orientation='vertical')
        chessboard_gui_boxlayout.add_widget(
            Image(source="./data/images/chess-pieces/DarkerGreenGreyChessBoard.png", pos=self.pos, keep_ratio=True, allow_stretch=True))  # default size_hint of (1,1) claims all of remaining height
        chessboard_gui_boxlayout.add_widget(repertoire_boxlayout)
        self.add_widget(chessboard_gui_boxlayout)
Related