Skip to content
Home » Kivy Part 11 –Advanced Scaling and Positioning

Kivy Part 11 –Advanced Scaling and Positioning

Spread the love

In the previous parts we saw how widgets on their own and widgets in layouts are positioned and scaled. Before we move on, let’s recapitulate briefly on what we already covered about scaling and positioning.

But before we delve into the topic, here’s some info for you.

*****

Book Info

I just published my Kivy book, GUI Programming with Python and Kivy. It’s pretty long (over 800 pages) and comprehensive. And, which also counts, easy to read. The book contains lots of illustrations.

This book covers all the basics that you need to know to start programming GUI applications with Python and Kivy. Throughout the book we are building a GUI application from scratch, a fully functional game using all kinds of tools that Kivy has to offer. It’s our Slugrace project, but covered in a much more in-depth manner.

Each part of the book starts with a theoretical introduction of a topic or idea that we then implement in the project. I assume you have no prior knowledge of the Kivy library, but you should have at least some basic knowledge of the Python programming language, including the object-oriented programming paradigm as this is what we will be using a lot in this book.

Kivy book

The book covers all the basic elements of Kivy that you have to know, like widgets, layouts, Kivy ids and properties, graphics, screens, animation, sound. Finally we’ll deploy the app to Windows. It is pretty comprehensive and after you finish it, I’m sure you’ll be able to create your own awesome GUI apps of any kind, not just games.

I hope you will have at least as much fun reading the book as I had writing it.

As far as this Kivy series is concerned, the following parts will contain the most important elements covered in the book. However, some elements will be presented in a simplified way here on my blog or omitted completely.

____________

If you are interested, you can purchase the book in four versions. Here are the links:

1) ebook – pdf version on my website – in full color

Here you can see the description of the book, sample graphics from the book and the full table of contents.

2) ebook – Kindle version on Amazon – in full color

3) paperback version on Amazon – in black and white

4) paperback version on Amazon – in full color

*****

And Now Let’s Move On…

So, if you want to scale a widget which is not inside a layout, you use the properties size, width and height. If you want to position such a widget, you should use the pos property. All these properties use fixed numbers of pixels.

Now, if you want to scale a widget inside a layout, you should use one of the following properties: size_hint, size_hint_x or size_hint_y. They are used with proportions rather than fixed numbers of pixels, so the value you assign to them should be between 0 and 1. If you want to position a widget inside a layout, you use the pos_hint property, to which you assign a dictionary with one or more of the following properties: x, center_x, right (for horizontal positioning), y, center_y, top (for vertical positioning). The values are proportions again, so they should be in a range from 0 to 1. One more thing we discussed in the previous part is that the proportions may also be outside the range from 0 to 1 if you want the widget or part of it to be outside the visible program window.

Fine, you already know how to scale and position widgets, both on their own and inside layouts. But there are still some more options to explore. Let’s have a look at them now.

Using the x, center_x, right, y, center_y and top Properties In Layouts

You can use these properties with fixed numbers of pixels in layouts, but then you shouldn’t use the same properties in pos_hint. Here’s an example:

# File name: helloworld.kv
<CustomButton@Button>:
    size_hint: .2, .1

<FloatLayout>:     
    CustomButton:
        text: 'Button 1' 
        x: 0
        y: 0       
        
    CustomButton:
        text: 'Button 2'
        x: 200
        y: 200

If you run this program now, you will get the following window:

Using the x, center_x, right, y, center_y and top Properties In Layouts

Now the left borders of the two buttons (x) and their bottom borders (y) will be always the same, even if you resize the window.

Your Panda3D Magazine

Make Awesome Games and Other 3D Apps

with Panda3D and Blender using Python.

Cool stuff, easy to follow articles.

Get the magazine here (PDF).

Using the x, center_x, right, y, center_y and top Properties Outside Layouts

Some time ago we were using the x, y, right and top properties on the root object (it was in the part about custom widgets). Here’s the code again:

Python file:

# File name: main.py

import kivy
from kivy.app import App
from kivy.uix.button import Button
from kivy.uix.widget import Widget

class MyCustomButton(Button):
    pass

class MyCustomWidget(Widget):
    pass

class HelloWorldApp(App):
    def build(self):
        return MyCustomWidget()

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

kv file:

# File name: helloworld.kv

<MyCustomButton>:
    size: 120, 40
    color: .7, .6, .4, 1

<MyCustomWidget>: 
    TextInput:
        hint_text: 'Type Something'
        pos: root.x + 20, root.top - self.height - 20
        size: 300, 40
    MyCustomButton:
        text: 'Press Me'
        pos: root.x + 20, root.y + 20
    MyCustomButton:
        text: 'Press Me Too'
        pos: root.right - self.width - 20, root.y + 20

Here the properties refer to the root object, which is the MyCustomWidet object. If you run this program again, you will see the following:

Using the x, center_x, right, y, center_y and top Properties Outside Layouts

Try resizing the window and watch carefully how the elements behave. And now let’s rewrite the kv code as follows:

<MyCustomButton>:
    size: 120, 40
    color: .7, .6, .4, 1

<MyCustomWidget>: 
    TextInput:
        hint_text: 'Type Something'
        x: 20
        y: 400
        size: 300, 40
    MyCustomButton:
        text: 'Press Me'
        center_x: 60
        center_y: 20
    MyCustomButton:
        text: 'Press Me Too'
        right: 300
        top: 20

If you now run the app, it will look like this:

positioning properties

Using the pos Property Inside Layouts

The pos property is usually used for widgets, not for layouts. However you can use it for a layout if you need fixed numbers of pixels. Then, however, you must remember to not use pos_hint or otherwise it will override pos.

Here’s a simple example.

Python code:

import kivy
from kivy.app import App
from kivy.uix.floatlayout import FloatLayout

class HelloWorldApp(App):
    def build(self):
        return FloatLayout()

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

kv code:

# File name: helloworld.kv

<CustomButton@Button>:
    size_hint: .2, .1

<FloatLayout>:     
    CustomButton:
        text: 'Button 1' 
        pos: 20, 50      
        
    CustomButton:
        text: 'Button 2'
        pos: 500, 500

And here’s the program window:

Using the pos Property Inside Layouts

If you resize the window, the positions of the buttons won’t change.

Using the size, width and height Properties Inside Layouts for Scaling

You can also use the size, width and height properties for scaling in layouts. You must remember, however, to set size_hint, size_hint_x or size_hint_y (for size, width and height respectively) to None. In case of size_hint you should actually set it to (None, None). Otherwise it won’t take effect.

Python Jumpstart Course

Learn the basics of Python, including OOP.

with lots of exercises, easy to follow

The course is available on Udemy.

Here’s an example. The Python file is just like before and here’s the kv file:

# File name: helloworld.kv

<FloatLayout>:     
    Button:
        text: 'Button 1' 
        pos: 20, 50     
        size: 200, 20 
        
    Button:
        text: 'Button 2'
        pos: 500, 500
        size_hint: None, None
        size: 200, 20 

If you now run the application, this is what you will get:

Using the size, width and height Properties Inside Layouts

As you can see, although we set size to the same value for both buttons, 200 pixels wide and 20 pixels high, it only works with Button 2. This is because we didn’t set the first button’s size_hint property to (None, None). Let’s fix it:

# File name: helloworld.kv

<FloatLayout>:     
    Button:
        text: 'Button 1' 
        pos: 20, 50    
        size_hint: None, None 
        size: 200, 20 
        
    Button:
        text: 'Button 2'
        pos: 500, 500
        size_hint: None, None
        size: 200, 20 

Now it will work as expected for both buttons:

Using the size, width and height Properties Inside Layouts again

And now watch what will happen if we change just one line of code:

# File name: helloworld.kv

<FloatLayout>:     
    Button:
        text: 'Button 1' 
        pos: 20, 50    
        
        # Here's the difference.
        size_hint_x: None 
        size: 200, 20 
        
    Button:
        text: 'Button 2'
        pos: 500, 500
        size_hint: None, None
        size: 200, 20 

Blender Jumpstart Course

Learn the basics of 3D modeling in Blender.

step-by-step, easy to follow, visually rich

The course is available on Udemy and on Skillshare.

Now, for the first button, we only set the size_hint_x property to None, not size_hint. This will cause the size property to take effect only partially, in horizontal direction:

Using the size, width and height Properties Inside Layouts one more time

So now you know all you need about positioning and scaling widgets, both inside and outside layouts. I’m using the plural form, layouts, here, although the only layout we’ve been using so far is FloatLayout. In the next part we’ll have a look at the other layouts that we’ll be making use of in our application.


Spread the love

Leave a Reply