No doubt that fixed coordinates are the most flexible way of organizing elements in an n-dimensional space; however, it is very time-consuming. Instead, Kivy provides a good set of layouts instead, which facilitate the work of organizing widgets. A Layout
is a Widget
subclass that implements different strategies to organize embedded widgets. For example, one strategy could be organizing widgets in a grid (GridLayout
).
Let's start with a simple
FloatLayout
example. It works very similar to the way we organize widgets directly inside another Widget
, except that now we can use proportional coordinates (proportions of the total size of the window) rather than fixed coordinates (exact pixels). This means that we don't need the calculations we did in the previous section with self
and root
. The following is the Python code:
68. # File name: floatlayout.py 69. 70. from kivy.app import App 71. from kivy.uix.floatlayout import FloatLayout 72. 73. class FloatLayoutApp(App): 74. def build(self): 75. return FloatLayout() 76. 77. if __name__=="__main__": 78. FloatLayoutApp().run()
There is nothing new in the preceding code (floatlayout.py
) except for the use of FloatLayout
(on line 75). The interesting parts are in the Kivy language (floatlayout.kv
):
79. # File name: floatlayout.py 80. <Button>: 81. color: .8,.9,0,1 82. font_size: 32 83. size_hint: .4, .3 84. 85. <FloatLayout>: 86. Button: 87. text: 'Hello' 88. pos_hint: {'x': 0, 'top': 1} 89. Button: 90. text: 'World!' 91. pos_hint: {'right': 1, 'y': 0}
In the floatlayout.kv
code file, we use two new properties, size_hint
and pos_hint
, which work with the proportional coordinates with values ranging from 0 to 1; (0, 0) is the bottom-left corner and (1, 1) the top-right corner. For example, the size_hint
on line 83 sets the width to 40 percent of the current window width and the height to 30 percent of the current window height. Something similar happens to the pos_hint
but the notation is different: a Python dictionary where the keys (for example, 'x'
or 'top'
) indicate which part of the widget is referenced. For instance, 'x'
is the left border. Notice that we use the top
key instead of y
in line 88 and right
instead of x
in line 91. The top
and right
properties respectively reference the top and right edges of the Button
, so it makes the positioning simpler. That doesn't mean we could have used x
and y
for both the axes. For example, something like pos_hint: {'x': .85, 'y': 0}
on line 91. The right
and top
keys avoids some calculations and makes the code clearer. The next screenshot illustrates the output of the previous code with the available keys for the pos_hint
dictionary:
The available pos_hint
keys (
x
,
center_x
,
right
, y
, center_y
, and
top
) are useful for aligning to edges or centering. For example, pos_hint: {'center_x':.5, 'center_y':.5}
would align a Widget
in the middle, no matter what the size of the window is.
Could have we used top
and right
with the fixed positioning of widgets2.kv
(in line 64 and 67)? Yes, we could; but notice that pos
doesn't accept Python dictionaries ({'x':0,'y':0}
) that just lists of values (0,0
). Therefore, instead of using the pos
property, we have to use the x
, center_x
, right
, y
, center_y
, and top
properties directly. For example, instead of pos: root.x, root.top - self.height
, we would have used the following code:
x: 0 top: root.height
Notice that these properties always specify fixed values (pixels) and not proportional ones.
Note
If we want to use proportional coordinates, we have to be inside a Layout
(or an App
), and use the
pos_hint
property.
If we are using a Layout
instance, can we force the use of fixed values? Yes, but there can be conflicts if we are not careful with the properties we use. If we use any Layout
, then pos_hint
and size_hint
will have the priority. If we want to use fixed positioning properties (pos
, x
, center_x
, right
, y
, center_y
, and top
), we have to ensure that we are not using the pos_hint
property. Secondly, if we want to use the size
, height
, or width
properties, we need to give a None
value to the size_hint
axis we want to use with the absolute values. For example, size_hint: (None, .10)
allows using the height
property, but it keeps the width as 10 percent of the windows size. The following table summarizes everything we learned about the positioning and sizing properties. The first and second columns indicate the name of the property and its respective value. The third and fourth columns indicate if it is available for layouts and for widgets:
We have to be careful because some of the properties behave different according to the layout we are using. Kivy currently has seven different layouts; six of them are briefly described in the following table. The left column shows the name of the Kivy Layout
class and the right column describes briefly how they work:
The seventh layout, which is the
ScatterLayout
, works similar to RelativeLayout
but it allows multitouch gesturing for rotating, scaling, and translating. It is slightly different in its implementation so we will review it later. The Kivy API (http://kivy.org/docs/api-kivy.html) offers a detailed explanation and good examples on each of them. The behavioral difference of the properties depending on the Layout
is sometimes unexpected but the following are some of the hints that will help you in the GUI building process:
The
size_hint
,size_hint_x
, andsize_hint_y
properties work on all the layouts but the behavior might be different. For example,GridLayout
will try to take an average of thex
hints andy
hints on the same row or column respectively.It is advisable to use values from 0 to 1 with the
size_hint
,size_hint_x
, andsize_hint_y
properties. However, you can also use values bigger than 1. Depending on theLayout
, Kivy makes theButton
bigger than the container or tries to recalculate a proportion based on the sum of the hints on the same axis.The
pos_hint
property works only inFloatLayout
,RelativeLayout
, andBoxLayout
. InBoxLayout
, only the x keys (x
,center_x
, andright
) work in the vertical orientation and vice versa. An analogous rule applies for the fixed positioning properties (pos
,x
,center_x
,right
,y
,center_y
, andtop
).The
size_hint
,size_hint_x
, andsize_hint_y
properties can always be set asNone
in favor of size, width, and height.
There are more properties and particularities of each Layout
, but with the ones we have covered, you will be able to build almost any GUI you desire. In general, the recommendation is to use the layout as it is. Don't try to force the layout through an odd configuration of properties. Instead, it is better to use more layouts and embed them to reach our design goals. In the next section, we will teach you how to embed layouts, and we will offer a more comprehensive example of them.