Search code examples
pythonpython-3.xkivykivy-language

Kivy Layout square Stacking


I was making a program similiar to exel.
And then I ran into a issue.
StackLayout stacks good, but because the size of inputs is static it leave a blank space in some cases.

I try to do like size=(self.width/5, self.height/5).
If someone saw how exel look now that there are more inputs of the screen this is why I use ScrollLayout and I want only 5 inputs in one row(user can change it in display settings(I will do it then creating rest of UI))

Here is what I had tried for now.
main.py:

from kivy.metrics import dp
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.gridlayout import GridLayout
from kivy.uix.stacklayout import StackLayout
from kivy.uix.textinput import TextInput


class EditorGrid(BoxLayout):
    def __init__(self, **kwargs):
        super().__init__(**kwargs)
        size = dp(self.width / 5)
        print(size)
        for i in range(0, 100):
            b = TextInput(text=str(i + 1), size_hint=(None, None), size=(dp(size), dp(size)))
            self.add_widget(b)

    def on_size(self, *args):
        self.size = dp(self.width/5)
        print(self.size)
        pass


class pxApp(App):
    pass


if __name__ == "__main__":
    pxApp().run()

kivy file:

Scrolling:

<Scrolling@ScrollView>
    do_scroll_x: True
    do_scroll_y: True
    EditorGrid:
        size_hint: 1, None
        height: self.minimum_height

<EditorGrid>:

There is next problem that in init window size is 100x100.


Solution

  • I recommend using setters in binding under kv script. If you want to apply it in python, you could use a binding function for each button.

    b = TextInput(.......) #omit size_hint and size attributes
    #the following function is called every time EditorGrid(self) size_hint changes when the function is bind
    #The function could be defined in a outer scope.
    #Look at kivy callback functions to better understand the syntax
    binding_function = lambda ins, *a: setattr(ins, 'size_hint', tuple((dim/5 for dim in self.size_hint))
    b.bind(size_hint=binding_function)