user6142489
user6142489

Reputation: 532

Kivy: Why is BoxLayout pushing my button to the bottom?

I'm new to Kivy, but trying to get the hang of it. I'm working through the example in "Creating Apps in Kivy" as a template, but I've even stumbled in the first chapter. For some reason, my buttons are getting pushed to the bottom of the App. Am I missing something critical that they are showing up down there?

My python file:

import kivy

from kivy.app import App
from kivy.uix.button import Label
from kivy.uix.boxlayout import BoxLayout

# In the kv file, everything to the right of the colon is pure python
# for loading python module in kv file, use format of #:  import keyword module_name
class WeatherWidget(BoxLayout):
    def printing_test(self):
        print('This is a test')

class DailyViewApp(App):
    def build(self):
        return WeatherWidget()

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

My kv file:

<WeatherWidget>:
    orientation: "vertical"
    BoxLayout: 
        height: "30dp"
        size_hint_y: None
        Button: 
            text: 'New York, NY' 
            size_hint_x: 1
            on_press: root.printing_test()
        Button: 
            text: 'Test'
            size_hint_x: 0.25

My (incorrect) output:

Upvotes: 2

Views: 3915

Answers (2)

ikolim
ikolim

Reputation: 16041

In BoxLayout and vertical orientation, the first widget is placed at the bottom of the window and scroll upwards when more widgets are added below. If you want it to appear at the top of the window, you will have to either use pos, or add another boxlayout (size_hint_y = 0.9) to fill up the remaining space, or add widgets until it fill up the remaining space. With pos, you will have to compute the height as shown in Example 1.

pos: 0, root.height - 30

If you are going to place more widgets below the buttons/in the outter boxlayout, I would recommend using GridLayout as the root widget as shown in Example 2.

Example 1 - Nested BoxLayout

dailyview.kv

#:kivy 1.10.0

<WeatherWidget>:
    orientation: "vertical"
    pos: 0, root.height - 30
    BoxLayout:
        height: "30dp"
        size_hint_y: None
        Button:
            text: 'New York, NY'
            size_hint_x: 1
            on_press: root.printing_test()
        Button:
            text: 'Test'
            size_hint_x: 0.25

Output 1 - Nested BoxLayout

enter image description here

Example 2 - GridLayout

main.py

from kivy.app import App
from kivy.uix.gridlayout import GridLayout

# In the kv file, everything to the right of the colon is pure python
# for loading python module in kv file, use format of #:  import keyword module_name


class WeatherWidget(GridLayout):
    def printing_test(self):
        print('This is a test')


class DailyViewApp(App):
    def build(self):
        return WeatherWidget()


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

dailyview.kv

#:kivy 1.10.0

<WeatherWidget>:
    cols: 1
    BoxLayout:
        height: "30dp"
        size_hint_y: None
        Button:
            text: 'New York, NY'
            size_hint_x: 1
            on_press: root.printing_test()
        Button:
            text: 'Test'
            size_hint_x: 0.25

Output 2 - GridLayout

enter image description here

Upvotes: 5

sp________
sp________

Reputation: 2645

Another solution is just to put another widget after the first boxlayout which contains the buttons to cover the remaining place

<WeatherWidget>:
    orientation: "vertical"
    BoxLayout: 
        height: "30dp"
        size_hint_y: None
        Button: 
            text: 'New York, NY' 
            size_hint_x: 1
            on_press: root.printing_test()
        Button: 
            text: 'Test'
            size_hint_x: 0.25
    BoxLayout:
        size_hint_y: .9 #this is a random number that I have chosen

Upvotes: 4

Related Questions