stacklayout pos_hint not working for top element

409 views
Skip to first unread message

Dean-O Rochester

unread,
Jul 14, 2021, 10:30:13 AM7/14/21
to Kivy users support
Hi all
I have trying to get the top label to be just below the top navbar and I cant seem to get the pos_hint line to have any affect.  I resize the window or change the y value and it is always in the same place.  How can I get the elements in the screen to start below the top navbar?

Thanks in advance
Dean-O

Here is my code

from kivy.lang import Builder
from kivy.uix.boxlayout import BoxLayout
from kivy.properties import ObjectProperty

from kivy.uix.stacklayout import StackLayout

from kivymd.app import MDApp

KV = '''
<ContentNavigationDrawer>:

    ScrollView:

        MDList:

            OneLineListItem:
                text: "Screen 1"
                on_press:
                    root.nav_drawer.set_state("close")
                    root.screen_manager.current = "scr 1"

            OneLineListItem:
                text: "Screen 2"
                on_press:
                    root.nav_drawer.set_state("close")
                    root.screen_manager.current = "scr 2"


Screen:

    MDToolbar:
        id: toolbar
        pos_hint: {"top": 1}
        elevation: 10
        title: "MDNavigationDrawer"
        left_action_items: [["menu", lambda x: nav_drawer.set_state("open")]]

    MDNavigationLayout:
        x: toolbar.height

        ScreenManager:
            id: screen_manager

            Screen:
                name: "scr 1"

                StackLayout:
                    orientation: "tb-lr"
                    pos: 0, 0
                    

                    MDLabel:
                        text: "123456"
                        size_hint: (None, None)
                        pos_hint: {'right': 0, 'top': 0.75}

                    MDRectangleFlatButton:
                        text: "MDRECTANGLEFLATBUTTON 1"
                        theme_text_color: "Custom"
                        text_color: 1, 0, 0, 1
                        line_color: 0, 0, 1, 1
                        size_hint: (None, None)

                    MDRectangleFlatButton:
                        text: "MDRECTANGLEFLATBUTTON 2"
                        theme_text_color: "Custom"
                        text_color: 1, 0, 0, 1
                        line_color: 0, 0, 1, 1
                        size_hint: (None, None)
                            
                        


            Screen:
                name: "scr 2"

                BoxLayout:
                    orientation: "vertical"
                    pos: 0, root.height - 150
                    BoxLayout:
                        padding: "8dp"
                        orientation: "vertical"
                        height: "60dp"
                        size_hint_y: None
                        pos: 0, root.height - 100
                        Button:
                            text: 'New York, NY'
                            size_hint_x: .5
                            on_press: root.printing_test()
                        Button:
                            text: 'Test'
                            size_hint_x: 0.25

        MDNavigationDrawer:
            id: nav_drawer

            ContentNavigationDrawer:
                screen_manager: screen_manager
                nav_drawer: nav_drawer
'''


class ContentNavigationDrawer(BoxLayout):
    screen_manager = ObjectProperty()
    nav_drawer = ObjectProperty()


class TestNavigationDrawer(MDApp):
    def build(self):
        return Builder.load_string(KV)


TestNavigationDrawer().run()


Elliot Garbus

unread,
Jul 15, 2021, 12:44:09 PM7/15/21
to kivy-...@googlegroups.com

I made changes to the RootLayout and Screen 1.  I Changed the Root from a screen to a MDBoxLayout.  A Screen is a RelativeLayout.  A BoxLayout will position the widgets the way you want.  The other ‘trick’ was to add an empty boxlayout underneath the items you are positioning.  This empty BoxLayout has a default sizehint of 1 so will fill the available space, positioning the widgets above it at the top of the enclosing layout.

 
 
from kivy.lang import Builder
from kivy.uix.boxlayout import BoxLayout
from kivy.properties import ObjectProperty

from kivy.uix.stacklayout import StackLayout

from kivymd.app import MDApp

KV =
'''

<ContentNavigationDrawer>:
    ScrollView:
        MDList:
            OneLineListItem:
                text: "Screen 1"
                on_press:
                    root.nav_drawer.set_state("close")
                    root.screen_manager.current = "scr 1"
            OneLineListItem:
                text: "Screen 2"
                on_press:
                    root.nav_drawer.set_state("close")
                    root.screen_manager.current = "scr 2"

MDBoxLayout:     # changed from Screen.  A Screen is a RelativeLayout
    orientation: 'vertical'
    MDToolbar:
        id: toolbar
        # pos_hint: {"top": 1}

        elevation: 10
        title: "MDNavigationDrawer"
        left_action_items: [["menu", lambda x: nav_drawer.set_state("open")]]

    MDNavigationLayout:
        # x: toolbar.height


        ScreenManager:
            id: screen_manager
            Screen:
                name: "scr 1"
                MDBoxLayout:  # Changed from stacklayout.
                    orientation: 'vertical'
                    # pos: 0, 0
                    MDLabel:
                        text: "123456"
                        # size_hint: (None, None)
                        # pos_hint: {'right': 0, 'top': 0.75}
                        size_hint_y: None
                        height: dp(24)


                    MDRectangleFlatButton:
                        text: "MDRECTANGLEFLATBUTTON 1"
                        theme_text_color: "Custom"
                        text_color: 1, 0, 0, 1
                        line_color: 0, 0, 1, 1
                        # size_hint: (None, None)


                    MDRectangleFlatButton:
                        text: "MDRECTANGLEFLATBUTTON 2"
                        theme_text_color: "Custom"
                        text_color: 1, 0, 0, 1
                        line_color: 0, 0, 1, 1
                        # size_hint: (None, None)
                    MDBoxLayout:
                        # this is a placeholder  The other objects are sized so this fills the remaining space

--
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/804b6a9b-2d5d-43ff-ac09-ad0ec68e405cn%40googlegroups.com.

 

Dean-O Rochester

unread,
Jul 19, 2021, 12:00:16 PM7/19/21
to Kivy users support
Hi ElliotG

I am trying to get my head around the positioning of things in kivy kivymd.

Is there a good guide to positioning things in kivy and kivymd, with examples, etc?

I put questions after your changes to ask why you did this or that

Thanks for your assistance 
Dean-O

KV =
'''

<ContentNavigationDrawer>:
    ScrollView:
        MDList:
            OneLineListItem:
                text: "Screen 1"
                on_press:
                    root.nav_drawer.set_state("close")
                    root.screen_manager.current = "scr 1"
            OneLineListItem:
                text: "Screen 2"
                on_press:
                    root.nav_drawer.set_state("close")
                    root.screen_manager.current = "scr 2"

MDBoxLayout:     # changed from Screen.  A Screen is a RelativeLayout
                                     ## this makes sense.  Example I had for navbar toolbar was with screens... didn't know that a screen was relative layout

    orientation: 'vertical'
    MDToolbar:
        id: toolbar
        # pos_hint: {"top": 1}    ## why did you comment this out?

        elevation: 10
        title: "MDNavigationDrawer"
        left_action_items: [["menu", lambda x: nav_drawer.set_state("open")]]

    MDNavigationLayout:
        # x: toolbar.height


        ScreenManager:
            id: screen_manager
            Screen:
                name: "scr 1"
                MDBoxLayout:  # Changed from stacklayout.
                                               ## why not use stacklayout?  the examples I saw I thought it let you do the top down stacking of things easier.  No?

                    orientation: 'vertical'
                    # pos: 0, 0     ## why did you comment this out?  

                    MDLabel:
                        text: "123456"
                        # size_hint: (None, None)      ## why did you comment these two lines out?  I thought that they did what your two lines are doing.

                        # pos_hint: {'right': 0, 'top': 0.75}
                        size_hint_y: None
                        height: dp(24)


                    MDRectangleFlatButton:
                        text: "MDRECTANGLEFLATBUTTON 1"
                        theme_text_color: "Custom"
                        text_color: 1, 0, 0, 1
                        line_color: 0, 0, 1, 1
                        # size_hint: (None, None)   ## why did you comment this out?


                    MDRectangleFlatButton:
                        text: "MDRECTANGLEFLATBUTTON 2"
                        theme_text_color: "Custom"
                        text_color: 1, 0, 0, 1
                        line_color: 0, 0, 1, 1
                        # size_hint: (None, None)   ## why did you comment this out?

                    MDBoxLayout:
                        # this is a placeholder  The other objects are sized so this fills the remaining space
                              ## this is way I used stack layout to not have to do this, but there doesnt appear to be a means to push things to the top and the only way is to do this empty element trick?

Elliot Garbus

unread,
Jul 19, 2021, 12:57:36 PM7/19/21
to kivy-...@googlegroups.com

The key concept to learn about kivy (or any GUI) is the Layouts.  The layouts handle the positioning of the widgets for you.  In a FloatLayout, you have to position and size all of the widgets.  In a BoxLayout, the Layout will size and position the widgets for you.  Layouts are tools for positioning and sizing widgets.

 

Read through the documentation for all of the Layouts.  In the Kivy-examples directory you can find the ‘kivy catalog’, it provides a number of interactive screens that let you interactively write kv and see the changes that result.   You need to spend time building small examples and playing with size and size_hints and the Layouts to build an deeper understanding of how they work.  This was very frustrating for me when I first started using kivy.   BoxLayout is perhaps the most frequent layout I use.  Build a small example, look at how hints work, look how unsized spaces will grow to fill available space.  It takes some experience to make the lights go one.

 

My Comments below in blue

                               # I only use screens in a ScreenManager.


    orientation: 'vertical'
    MDToolbar:
        id: toolbar

        # pos_hint: {"top": 1}    ## why did you comment this out?  The BoxLayout was positioning this widget.  This hint has no effect in a vertical BoxLayout.


        elevation: 10
        title: "MDNavigationDrawer"
        left_action_items: [["menu", lambda x: nav_drawer.set_state("open")]]

    MDNavigationLayout:

        # x: toolbar.height



        ScreenManager:
            id: screen_manager
            Screen:
                name: "scr 1"

                MDBoxLayout:  # Changed from stacklayout.

                                               ## why not use stacklayout?  the examples I saw I thought it let you do the top down stacking of things easier.  No?

                                                #  A vertical BoxLayout is a very easy way to size these kinds of widgets.


                    orientation: 'vertical'
                    # pos: 0, 0     ## why did you comment this out?  The BoxLayout is in the screen this is the default position, given your layout.  It has no effect.

 


                    MDLabel:
                        text: "123456"
                        # size_hint: (None, None)      ## why did you comment these two lines out?  I thought that they did what your two lines are doi

                        # pos_hint: {'right': 0, 'top': 0.75}

                        size_hint_y: None                    # This line turns off the size hint for height.  The height attribute sets the height.  The width hint defaults to 1
                        height: dp(24)                           # The label will use the full width, but the height will be fixed.  The BoxLayout will used this fixed height to

                                                                             # calculate the positions of the other widgets.



                    MDRectangleFlatButton:
                        text: "MDRECTANGLEFLATBUTTON 1"
                        theme_text_color: "Custom"
                        text_color: 1, 0, 0, 1
                        line_color: 0, 0, 1, 1

                        # size_hint: (None, None)   ## why did you comment this out?   # if you are going to turn off the hints you should set the size.  This had no effect.



                    MDRectangleFlatButton:
                        text: "MDRECTANGLEFLATBUTTON 2"
                        theme_text_color: "Custom"
                        text_color: 1, 0, 0, 1
                        line_color: 0, 0, 1, 1

                        # size_hint: (None, None)   ## why did you comment this out?  Same above

                    MDBoxLayout:
                        # this is a placeholder  The other objects are sized so this fills the remaining space

                              ## this is way I used stack layout to not have to do this, but there doesnt appear to be a means to push things to the top and the only way is to do this empty element trick?

                              # Yes this is a way to do this with BoxLayout.  You could use other layouts to position the widgets with the same end result. 

                              # I find this easy to understand and maintain.  If I need to add more widgets – I just add them and this place holder will shrink.

 

Reply all
Reply to author
Forward
0 new messages