Dynamically generated dropdown menu

88 views
Skip to first unread message

xyz xyz

unread,
May 13, 2024, 9:52:28 AMMay 13
to Kivy users support
Hi,

My problem is two-fold.
Overall goal is 1) a dropdown-list with a dynamic number of buttons, that b) scales with the  the main screen when the later becomes resized. I already achieved 1).  However, i always had to generate the dropdown and buttons within a python file, which seems to make 2) impossible (whenever i resize the screen - the py-generated buttons are not resized).

As of my understanding, The KV file is repsonsible for scaling of the UI when the window is resized. This is working with buttons, layouts etc that i am using within my screen in case those are defined by a KV-file..
Any py-generated button seems to be static in size after creation and wont scal with any resizve of the mainscreen.. 

This leads me to the conlcusion, i have to define a "template"-like button or layout within a kv-file, that then somehow ("magically") is used after the dropdown, which contains the buttons, is generated, so that the KV takes of resizing.

Sorry for this probably weird sounding description, but i am not able to define it better in words. Unluckily i cannot provide code, as i am trying to visualize some larger company-scripts with kivy. 

I realy appreaciate help here or a description, what i understood wrongly, here, as it seems that i also dont get the concept of kivy 100% right.

Thanks in advance 

ElliotG

unread,
May 13, 2024, 10:28:38 AMMay 13
to Kivy users support
There is nothing you can do in KV, that you can not do in Python.
KV does a number of things automatically for you, in particular it can bind kivy properties automatically.  For example,

BoxLayout:
    size_hint: None, None
    size: self.minimum_size

In the code above, if the minimum_size property changes it will update the size attribute of the BoxLayout.
You can do the same thing in Python using the bind() method of widgets or the on_minimum_size event that is created by kivy properties.
Read: 

If you can share a minimal example that demonstrates your issue, I would be happy to help.
You may find that a Spinner is easier to use that a DropDown.  A DropDown allows you to create a customized Spinner, if you don't need the customization, use a Spinner.

xyz xyz

unread,
May 14, 2024, 2:39:24 AMMay 14
to Kivy users support
Hey,

here is a "minimum" code example that i guess i can share.

1. Clears the dropdown with the ID: ID_DD_Ports
2. Cycles through a List:
2.1 Creates a Layout per entry
2.2 Creates a checkbox per entry
2.3 Creates a label per entry
2.4 Adds checkbox and label to layout
2.5 Adds the layout to the dropdown with ID: ID_DD_Ports

The method:


    def CreateDropdown(self, List):
        self.ids.ID_DD_Ports.clear_widgets() #Temporary solution to force a rebuild

### Fetch the height of the "reference button"
        BtnHeight = self.ids.ID_Btn_PortDropdown.height

        for Element in List:
    ### Create a Checkbox
            Checkbox = CheckBox(active=True, size_hint=(None, None), size = (BtnHeight, BtnHeight), color=[0.2, 0.2, 0.2, 1])
    ### Use the current List-Element as Label
    PortLabel = Label(text=str(Element))
    ### Create an entry containig the checkbox and label
            EntryLayout = BoxLayout(orientation="horizontal", size_hint_y = None, height = BtnHeight)
            EntryLayout.add_widget(PortLabel)
            EntryLayout.add_widget(Checkbox)
            #EntryLayout.bind(minimum_size=EntryLayout.setter('size'))
            #Checkbox.bind(size=Checkbox.setter('size'))
    ### Add the Layout to the Dropdown with the ID "ID_DD_Ports"
            self.ids.ID_DD_Ports.add_widget(EntryLayout)
        return


All the buttons, layouts and so on, that are defined within the KV-file, can be resized on the fly. The checkbox and the boxlayout are generated in this method, and wont resize assumingly due to the "size_hint"-paramenter. However, if i skip size_hint, i dont see the dropdown-list at all.

For a better visualization, here is a screenshot how my very experimentell GUI looks like when i attach two devices on COM3 and COM5 (they ports are stored in the List after pressing the Scanbutton ).


Unbenannt.png

elli...@cox.net

unread,
May 14, 2024, 1:04:59 PMMay 14
to Kivy users support
Here is an example that shows a DropDown that where the width of the buttons scale with the window,
FWIW, for buttons that contain text I usually use a fixed button size.

In the example the Scan Button, and the PortDropDown Button are placed in a Horizontal BoxLayout.  In order for them to scale with the Window, I use Labels as spacers.  You can remove the Label text and the effect will remain.  The Labels have a default hint of 1, their height is sized by the BoxLayout.  They server as scalable spacers.  The Buttons have a size_hint_x of .5, so they will be ½ the size of the spacers.

I used a kivy property to manage updating the list of Ports.  I hope this helps, feel free to ask any questions.  

from kivy.uix.dropdown import DropDown
from kivy.uix.button import Button
from kivy.uix.checkbox import CheckBox
from kivy.uix.boxlayout import BoxLayout
from kivy.lang import Builder
from kivy.app import App
from kivy.properties import ListProperty
from kivy.metrics import dp
from kivy.uix.label import Label

kv = """
AnchorLayout:
   BoxLayout:
       size_hint_y: None
       height: dp(48)
       Label:
           text: 'spacer'  # these are used to show using a widget to create space in a BoxLayout
       Button:
           text: 'Scan'
           size_hint_x: .5
           on_release: app.refresh_ports()
       Label:
           text: 'spacer'  # you can remove the text, or use Widget as a spacer
       PortDropDown:
           id: port_drop_down
           size_hint_x: .5  # this sets the relative width of the dropdown
       Label:
           text: 'spacer' # the default size_hint is 1, 1
       
"""

class PortDropDown(Button):
   ports = ListProperty(['COM1', 'COM2'])

   def __init__(self, **kwargs):
       super().__init__(**kwargs)
       self.drop_down = DropDown()
       self.text = 'Ports'
       self.bind(on_release=self.drop_down.open)
       # self.drop_down.bind(on_select=lambda instance, x: setattr(self, 'text', x))
       self.create_drop_down()

   def create_drop_down(self):
       for port in self.ports:
           cb = CheckBox(active=True, size_hint_x=None, width=dp(32))
           port_label = Label(text=port)
           entry_layout = BoxLayout(size_hint_y=None, height=dp(48))
           entry_layout.add_widget(cb)
           entry_layout.add_widget(port_label)
           self.drop_down.add_widget(entry_layout)

   def on_ports(self, *args): # called when ports is changed
       self.drop_down.clear_widgets()
       self.create_drop_down()


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

   def refresh_ports(self):
       self.root.ids.port_drop_down.ports = ['COM3', 'COM4', 'COM5', 'COM6']


PositionDropDown().run()


From: kivy-...@googlegroups.com <kivy-...@googlegroups.com> on behalf of xyz xyz <moorle...@gmail.com>
Sent: Monday, May 13, 2024 11:39 PM
To: Kivy users support <kivy-...@googlegroups.com>
Subject: [kivy-users] Re: Dynamically generated dropdown menu
 
--
You received this message because you are subscribed to the Google Groups "Kivy users support" group.
To unsubscribe from this group and stop receiving emails from it, send an email to kivy-users+...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/kivy-users/dd2b1f39-1985-46d5-b960-800441862db5n%40googlegroups.com.

xyz xyz

unread,
May 22, 2024, 2:30:02 AMMay 22
to Kivy users support
Hey,

sorry for the late reply:

Thanks a lot for your efforts.
I tried the code. Just from a visual judgement, the biggest difference - as you yourself state - is, that the buttons, that are generated by the KV-lang have a fixed height. This is a kind of behaviour is present in my own UI, as intended. It seems, as if the width-scaling of the dropdown-buttons seem to work right out of the box (considering the very basic nature of my UI).
However, i still dont get a scaling in button-height. Unluckily this does not work in your example as well.
 
I probably have to describe my issue a bit more precisely:
My goal, is, that while resizing the main window (actually while dragging the borders of the window-frame), both width and height of the buttons should scale accordingly. This works out of the box with any KV-lang defined buttons. As i cant (at least as of my skills) generate buttons dynamically within KV-lang, i have to generate them in PY. And this causes problems.

Why:
1) If "size_hint" is used with a height= / width=, then the buttons are visible but have a static height or width and dont scale.
2) If no "size_hint" is used, no buttons are shown (technically i assume these buttons would scale, but hey, they are invisible :/ )

I guess "size_hint" is the problem here (or any option, that disables scaling). However, without it, i cant make my buttons appear.

I am realy glad for any kind of support here.
Best regards,
Moor


ELLIOT GARBUS

unread,
May 22, 2024, 12:12:05 PMMay 22
to Kivy users support
The height of the buttons is not scaling in the example I created because the buttons  are sitting in a BoxLayout of fixed height.

Looking at the top of the kv code:

AnchorLayout:
   BoxLayout:
       size_hint_y: None  # This results in a fixed height for the BoxLayout
       height: dp(48)

The BoxLayout has a fixed height, so the elements in the Layout with a size_hint of 1 will grow to the height of the enclosing layout.   If you want the height to scale with the window size, you need to set a size_hint for the BoxLayout, then the enclosed widgets will scale with the Layout.

AnchorLayout:
   BoxLayout:
       size_hint_y: 0.1       # the height is managed by the hint
       # size_hint_y: None   # the height was fixed at dp(48)
       # height: dp(48)

FWIW I generally find that it is better to fix the height of buttons.

If the size_hint is set to None, the default size of widgets is 100, 100.

"that the buttons, that are generated by the KV-lang have a fixed height. "  This is not correct.

If you provide a complete minimal example with an explanation of the desired behavior, I'm sure I can provide better assistance.


Sent: Tuesday, May 21, 2024 11:30 PM

To: Kivy users support <kivy-...@googlegroups.com>
Subject: Re: [kivy-users] Re: Dynamically generated dropdown menu
 

xyz xyz

unread,
May 27, 2024, 2:22:38 AMMay 27
to Kivy users support
Note ahead: I am not well accustomed to the concept of "self" (beside other things :D ) - so please dont bother for the moment except it harms the functionality of the program.

"If you provide a complete minimal example with an explanation of the desired behavior, I'm sure I can provide better assistance."

I have attached the code of the KV-file and the Py-file and modified it, so that it should work without hardware or subscripts.
In this example, the buttons of the dropdown-list are generated based on the amount of entries/keys within a dict. I have given a static dict to circumvent the device-detection. It contains a single entry.
Current behaviour:
The buttons, that are generated in the list, do scale in width, when the main window is resized by dragging on its frame. E.g. i open up the dropdownlist, which shows me several entries with Comports. Then, while showing the dropdown-list, i resize the main window and simultaneously the width of all buttons is changed. This is not true for the height.
Goal:
The height should scale as well. In other words, the height of the buttons in the dropdown should always have the same height as the button with the label "SCU at port". 


Py-File: Subscripts "DevIdent" and "SericalCom" are commented out and replaced by a static dict, representing the resulting dict (self.PortsUsedByDevDict).
from kivy.app import App
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.label import Label
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.uix.checkbox import CheckBox
from kivy.core.window import Window
from kivy.graphics import Color, Rectangle
from kivy.config import Config
from kivy.lang import Builder

# Subscripts in \src\*
#from src import DevIdent
#from src import SerialCom
#KV-Options
Config.set('graphics', 'resizable', True)

# KV-script loader
Builder.load_file(".//GUI//MainScreen.kv")

### Things that go to Options or config files one day:
# Options that controls the initial checkmark - True or False
StartupMarkAll = True

# Event fired classes

class RootScreen(ScreenManager):
    pass

class MainScreen(Screen):

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

    def CreatePrimaryDict(self):
        #self.ID_Dict = DevIdent.importConf(".\\conf\\IDList.config") # Imports Devices with their PID and VID
        #self.PortsUsedByDevDict = DevIdent.createPortDict(self.ID_Dict)
        self.PortsUsedByDevDict = {'COM3': {'device': 'Names'}}
        print(self.PortsUsedByDevDict)
        self.CreateDropdown(self.PortsUsedByDevDict, StartupMarkAll)
        pass

# Is working, but the height of the DD-Buttons are not scaling when the window-size is changed by dragging
    def CreateDropdown(self, Dict, StartupBool):
        self.ids.ID_DD_Ports.clear_widgets()        
        # Fetch the height of the "reference button"
        self.BtnHeight = self.ids.ID_Btn_PortDropdown.height

        IsActive = StartupBool
        ComPortList = list(Dict.keys())

        for self.ComPort in ComPortList:
            # Create a Checkbox
            self.Checkbox = CheckBox(active=IsActive, size_hint=(None, None), size = (self.BtnHeight, self.BtnHeight), color=[1, 1, 1, 1])
            self.Checkbox.id = format(self.ComPort)
            self.Checkbox.bind(active=self.IsPortUsed)

            #Use the current List-Element as Label
            PortLabel = Label(text=str(self.ComPort))
            #Create an entry containig the checkbox and label
            EntryLayout = BoxLayout(orientation="horizontal", size_hint_y = None, height = self.BtnHeight)
            EntryLayout.add_widget(PortLabel)
            EntryLayout.add_widget(self.Checkbox)
            #Add the Layout to the Dropdown with the ID "ID_DD_Ports"
            self.ids.ID_DD_Ports.add_widget(EntryLayout)

        return None

    def IsPortUsed(self, checkbox, value):
        SCUStateList = [checkbox.id, value]
        print("Bool: ", value, ", Port: ", checkbox.id) #DEBUG
        return SCUStateList

class ConnectorApp(App):
    title = "Connector App"

    def build(self):
        root_widget = RootScreen()  # Creates an instance of RootWidget
        main_screen = MainScreen()  # Creates an instance of MainScreen
        root_widget.add_widget(main_screen)  # Adds MainScreen to RootWidget
        return root_widget

if __name__ == '__main__':
    ConnectorApp().run()
KV-File:
<MainScreen>:
    Screen:
        id: MainScreenID

        FloatLayout:
            size: root.size
            RecycleView:
                size_hint: 1, 1

            FloatLayout:
                id: MenuBarID
                size_hint_y: 0.05
                pos_hint: {'center_x': 0.5, 'top': 1}
                canvas.before:
                    Color:
                        rgba: 1, 0, 0, 1 #Red
                    Rectangle:
                        size: self.size
                        pos: self.pos
           
                Button:
                    id: ID_Btn_Devices
                    text: "File"
                    size_hint: (0.1, 1)
                    pos_hint: {'left': 0, 'top': 1}
                    on_parent: ID_DD_FileMenu.dismiss()
                    on_release: ID_DD_FileMenu.open(self)

                    DropDown:
                        id: ID_DD_FileMenu
                        size_hint_y: None
                        size: ID_Btn_Devices.size

                        Button:
                            id: ID_Btn_1
                            text: "Btn_1"
                            size_hint_y: None
                            size: ID_Btn_Devices.size

                        Button:
                            id: ID_Btn_2
                            text: "Btn_2"
                            size_hint_y: None
                            size: ID_Btn_Devices.size

                Button:
                    id: ID_Btn_Options
                    size_hint_x: None
                    size_hint_y: 1
                    size: self.height, self.height
                    pos_hint: {'right': 1, 'top': 1}
                    # on_parent: ID_DD_FileMenu.dismiss()
                    # on_release: ID_DD_FileMenu.open(self)



            FloatLayout:
                id: ConnectionControlsID
                size_hint_y: 0.3
                pos_hint: {'center_x': 0.5, 'top': 0.95}
                canvas.before:
                    Color:
                        rgba: 0, 1, 0, 1  # Green color
                    Rectangle:
                        size: self.size
                        pos: self.pos

                Button:
                    id: ID_Btn_Scan
                    text: "Scan"
                    size_hint: (0.1, 0.25)
                    pos_hint: {'center_x': 0.075, 'center_y': 0.75}
                    on_press: root.CreatePrimaryDict()

                Button:
                    id: ID_Btn_PortDropdown
                    text: "Device at port"
                    size_hint: (0.15, 0.25)
                    pos_hint: {'center_x': 0.25, 'center_y': 0.75}
                    on_parent: ID_DD_Ports.dismiss()
                    on_release: ID_DD_Ports.open(self)

                DropDown:
                    id: ID_DD_Ports
                    canvas.before:
                        Color:
                            rgba: 0.8, 0.8, 0.8, 1
                        Rectangle:
                            size: self.size
                            pos: self.pos

            FloatLayout:
                id: TerminalID
                size_hint_y: 0.65
                pos_hint: {'center_x': 0.5, 'top': 0.65}
                canvas.before:
                    Color:
                        rgba: 0, 0, 1, 1  # Blue color
                    Rectangle:
                        size: self.size
                        pos: self.pos

<RootScreen>:
    MainScreen:

xyz xyz

unread,
May 27, 2024, 3:47:18 AMMay 27
to Kivy users support
The button, defined in the next example, behaves exactly as the buttons of the dropdown should do (generated by ChatGPT).
from kivy.app import App
from kivy.uix.button import Button
from kivy.uix.anchorlayout import AnchorLayout
from kivy.core.window import Window

class MyApp(App):
    def build(self):
        self.root = AnchorLayout()
       
        # Create a button with size_hint set to None to use exact size
        self.button = Button(text='Resizable Button', size_hint=(None, None))
       
        # Add the button to the AnchorLayout
        self.root.add_widget(self.button)
       
        # Bind the window size to the update_size method
        Window.bind(on_resize=self.update_size)
       
        # Set initial size
        self.update_size(Window, Window.size[0], Window.size[1])
       
        return self.root

    def update_size(self, instance, width, height):
        # Update button size based on window size to 10% of width and height
        self.button.size = (width * 0.1, height * 0.1)

if __name__ == '__main__':
    MyApp().run()
However, the moment i implement this into the dropdownlist / layouts, the button no longer scales. I assume this to be related to a fixed size of the layout, which supresses the automatic resize of the buttons...but, on ly the 2 cents from a beginner.

ElliotG

unread,
May 27, 2024, 1:10:49 PMMay 27
to Kivy users support
To get the desired effect, the height of the button needs to be changed dynamically.  I have used kivy properties to achieve the result.

Under App I added a kivy property called dd_height.
class ConnectorApp(App):
    title = "Connector App"
    # created a kivy property in app, so it is easy to access
    dd_height = NumericProperty()


In the kv for the button, I set the dd_height when the height of the button changes.

            Button:
                id: ID_Btn_PortDropdown
                text: "Device at port"
                size_hint: (0.15, 0.25)
                pos_hint: {'center_x': 0.25, 'center_y': 0.75}
                on_parent: ID_DD_Ports.dismiss()
                on_release: ID_DD_Ports.open(self)
                on_height: app.dd_height = self.height

I create the BoxLayout for EntryLayout in kv.  This automatically applies the bind.  This way the height of the layout that contains the Label and checkbox will size with the PortDropDown.
<EntryLayout>:
    orientation: 'horizontal'
    size_hint_y: None
    height: app.dd_height


And I made the required changes in create_drop_down, to use the new EntryLayout class.
working code attached.

mainscreen.kv
main.py

xyz xyz

unread,
May 28, 2024, 2:00:45 AMMay 28
to Kivy users support
You, sir, are a hero :D.
Since i began with Kivy, i failed in this specific topic over and over again.

Anyway, i guess i understood the approach and its simple and elegant. However, i just realized how few i understand in terms of interaction of Py and KV and which file is in control of what.
Whatsoever, i didnt expected such a neat solution, thanks!

Out of interest, yesterday i started an approach using "on_resize" to read out the buttons height and then use it to update the size of buttons of the dropdown. I didnt finished the approach, but would this have been valid as well? I can imagine that this puts some strain on the hardware?
### NOT YET FINISHED!

from kivy.app import App
from kivy.uix.button import Button
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.anchorlayout import AnchorLayout
from kivy.core.window import Window

from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.lang import Builder

Builder.load_string("""
<MainScreen>:
    FloatLayout:
        size: root.size
        Button:
            id: ID_Btn_test
            text: "File"
            size_hint: (0.2, 0.2)
            pos_hint: {'center_x': 0.5, 'center_y': 0.5}

    # BoxLayout:
       
    #     AnchorLayout:

    #         Button:
    #             id: ID_Btn_Test
    #             text: "Btn_Test"
    #             size_hint: None, None
""")

class MainScreen(Screen):
    pass

class MainApp(App):
    def build(self):
        self.sm = ScreenManager()
        self.main_screen = MainScreen(name='main')
        self.sm.add_widget(self.main_screen)
       
        # Access the button using its ID
        self.btn_test = self.main_screen.ids.ID_Btn_test

###=========================================================
        #####  HIER LIEGT DIE MAGIE!!!! on_resize!
        # Bind the window size change to the update_size method
        Window.bind(on_resize=self.update_size)
###=========================================================
        # Set initial size
        self.update_size(Window, Window.size[0], Window.size[1])

        return self.sm


    def update_size(self, instance, width, height):
        # Access the button using its ID
        btn_test = self.main_screen.ids.ID_Btn_test
        btn_size = btn_test.size
        print("Button size: " +str(btn_size))
       
        # Print out the size of the button
        #print(f'Button size: {self.btn_test.size}')

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

xyz xyz

unread,
May 28, 2024, 10:49:40 AMMay 28
to Kivy users support
At least to my understanding, i have to create for each kind of "element" a class, e.g. checkboxes, labels, etc. This would result in a lot of empty classes, with - as of my understanding - the sole function of listening to events like a resizing of the window. Correct?

You mentioned, that with this method the "bind"ing of the app.height has been done automatically. Is there a way, to hand over the same functionality to an element when its created? As of my understanding, any height that is handed over at element-creation is a one-time event and wont allow access to the elements' height afterwards. As such i assume, you have to get access via a method, that listens to changes of the window. I used - successfully - on_rescale, however it was MUCH slower than your method (code below, an update of the former approach).

In the worst case i put the classes in a separate file and forget about them. But i would prefer not to. As i would have to define several elements which will sum up quite fast (labels, checkboxes, buttons and so on), i would be interested in how i can achieve this with a "bind" solution? Can you help me here?


Code for an "on_rescale" triggered update of a button:
from kivy.app import App
from kivy.uix.button import Button
from kivy.uix.label import Label
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.anchorlayout import AnchorLayout
from kivy.core.window import Window
from kivy.graphics import Color, Rectangle

        Window.bind(on_resize=self.on_resize_msg)
###=========================================================
        # Set initial size
        #self.on_resize_msg(Window, Window.size[0], Window.size[1])

        # Creates a layout containing a button with static dimensions within the Py-script
        # The Screenmanager can only contain a screen-widget (done before), which can only contain a Layout-widget, which then can hold the button-widget! Puuuhhh....
        # THIS IS THE BUTTON, WHICH AUTOMATICALLY SHOULD BE RESIZED BY the "on_resize" trigger!
        self.Anchor_Layout = AnchorLayout(pos_hint={'center_x': 0.5, 'y': 0.2})
        self.Py_Widget = Label(text='Resizable Button', size_hint=(None, None), size=(200, 50))
        with self.Py_Widget.canvas.before:
            Color(0.2, 0.7, 0.3, 1)  # Set the color (RGBA format)
            self.rect = Rectangle(pos=self.Py_Widget.pos, size=self.Py_Widget.size)
        self.Py_Widget.id = 'Py_Button'
        self.Anchor_Layout.add_widget(self.Py_Widget)
        # Add the button to the AnchorLayout
        self.main_screen.add_widget(self.Anchor_Layout)
        return self.sm

    def on_resize_msg(self, instance, width, height):
        # Access the button using its ID
        btn_test = self.main_screen.ids.ID_Btn_test
        btn_size = btn_test.size
        btn_width = btn_test.size[0]
        btn_height = btn_test.size[1]

        self.Py_Widget.height = btn_height
        self.Py_Widget.width = btn_width
        self.rect.size = self.Py_Widget.size
        self.rect.pos = self.Py_Widget.pos

        # print("Button width: " +str(btn_width))      
        # print("Button height: " +str(btn_height))
        # print("Button size: " +str(btn_size))
       
        # Print out the size of the button
        #print(f'Button size: {self.btn_test.size}')

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

ElliotG

unread,
May 28, 2024, 12:05:38 PMMay 28
to Kivy users support
The layouts are tools for sizing and positioning widgets.  If you effectively use the layouts you don't need to listen for a Window on_resize event, the layouts will resize and reposition the widgets.

I do not typically find that I have a lot of "empty" classes. 
"Is there a way, to hand over the same functionality to an element when its created?"
Yes each widget and kivy property has a bind method.  See: https://kivy.org/doc/stable/api-kivy.event.html#kivy.event.EventDispatcher.bind  Each property of the widget is also a kivy property.  In python you can use the bind method.  In kv the bind methods happen automatically.  It is part of the advantage of using kv.

"As of my understanding, any height that is handed over at element-creation is a one-time event and wont allow access to the elements' height afterwards."  You can still access the widget height, but if the height was fixed (size_hint None) it will not update unless the height is explicitly changed.  

"As i would have to define several elements which will sum up quite fast (labels, checkboxes, buttons and so on), i would be interested in how i can achieve this with a "bind" solution? Can you help me here?"  The BoxLayout has minium_height, minimum_width and minimum_size attributes.  These calculate the minimum size of the layout by summing the size of the children enclosed in the Layout.

If you are triggering layout changes based on a Window resize, it implies you are not effectively using the layouts.  

There is an app in the kivy examples directory called kivycatalog, you can find it here: .venv/share/kivy-examples/demo/kivycatalog/main.py  It includes an interactive kv editor.  Select BoxLayout from the dropdown menu and fool with the Layouts.

There is also a useful tool in the modules called inspector that will show you details of your layout in a running app.  
See: 

I'm happy to answer your questions.
Reply all
Reply to author
Forward
0 new messages