Have you ever wonder where did a Widget go in Kivy?

For efficiency reasons, the Kivy basic widgets are meant to be as simple as possible, and this is why they have no background colour or borders. Then, it is basically impossible to tell where they are by just observing the screen. The feature is good (efficiency first) but sometimes it makes it very difficult to tell what is happening when things didn’t go as we expected.

Since there is no WYSIWYG (What You See Is What You Get) available for Kivy, and hopefully never : D (because they generate horrible code) There is already a WYSIWYG: it is called Kivy-Designer (I will tell you about it as soon as I get to use it). However, most of us just prefer to do it ourself because we believe we are able to produce better code and be in complete control of it.

In this case, what can we use something instead for debugging? You can use the inspector (see the comment by Ben). The problem persist in the sense that you don’t have a constant whole picture of what is happening. So, here is my tip to know have a better understanding in the invisible widgets Kivy world.

Let’s start looking at the codes to illustrate the problem. The first one is the main.py:

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

class Widgets (FloatLayout):
    pass

class WidgetsApp(App):
    def build(self):
        return Widgets()

WidgetsApp().run()

There shouldn’t be anything to explain there, but you can always ask me. Here is the widgets.kv:

<Widgets>:
    AnchorLayout:
        anchor_x: 'right'
        anchor_y: 'bottom'
        GridLayout:
            cols: 3
            size_hint: .6,.6
            Label:
            StackLayout:
                orientation: 'lr-tb'
                Widget:
                    size_hint: .2,.2
                Button:
                    size_hint: .3,.3
                    text: "how?"
            Widget:
            Widget:

And here it a resulting screenshot:

Screenshot from 2013-10-02 18:15:54

The question is how did that button get there? At this point, you probably would prefer to take a pencil and try to sketch the small mess I did in the code. It would be nice if we could draw a Line at the border of the widgets using the Canvas. You probably don’t want to go Widget by Widget adding the necessary instruction. Let’s then redefine the Widget class rules. I just added the <Widget> to the widgetst.kv file:

<Widget>:
    canvas.after:
        Line:
            rectangle: self.x+1,self.y+1,self.width-1,self.height-1
            dash_offset: 5
            dash_length: 3

<Widgets>:
    AnchorLayout:
        anchor_x: 'right'
        anchor_y: 'bottom'
        GridLayout:
            cols: 3
            size_hint: .6,.6
            Label:
            StackLayout:
                orientation: 'lr-tb'
                Widget:
                    size_hint: .2,.2
                Button:
                    size_hint: .3,.3
                    text: "how?"
            Widget:
            Widget:

Here is the resulting screenshot:

Screenshot from 2013-10-02 18:13:23

I hope you think it is neat. It was my little inspiration moment of the year. I just took advantage of inheritance and the Kivy rules to overwrite the base class of all widgets.

What is important is the concept. So, here it is an extra example. What happen if you want to know where is one type of widgets? For example, let’s say a the StackLayout instances:

<Widget>:
    canvas.after:
        Line:
            rectangle: self.x+1,self.y+1,self.width-1,self.height-1
            dash_offset: 5
            dash_length: 3
<StackLayout>:
    canvas.after:
        Color:
            rgb: 1,0,0
        Line:
            rectangle: self.x+1,self.y+1,self.width-1,self.height-1
        Color:
            rgb: 1,1,1ot

<Widgets>:
    AnchorLayout:
        anchor_x: 'right'
        anchor_y: 'bottom'
        GridLayout:
            cols: 3
            size_hint: .6,.6
            Label:
            StackLayout:
                orientation: 'lr-tb'
                Widget:
                    size_hint: .2,.2
                Button:
                    size_hint: .3,.3
                    text: "how?"
            Widget:
            Widget:

Please note that in this case I didn’t use the dash attributes of line. I also used a different color, so it is easy to tell where the StackLayout intances are. Here is the final screenshot:

Screenshot from 2013-10-02 18:15:40

I hope you find this as helpful as I have found for programming my interfaces. Continue Kivying!

I did this comic quite a long time ago already but I never uploaded it. I lost it together with other three : ( . The good news is that I finally had time to redraw it.

stallman.resized

Btw, any tips that people can give me about:

  • Which pencil, paper or eraser to use? You can see that I never took any drawing course or similar.
  • How to clean the image after scanning? I use Gimp and adjust whites, bright & contrast, some filters but it takes me so long but I wonder if there is already an specialized tool for this. To be honest, I don’t have an scanner, I just take pictures with my phone.
  • Any software tool that can help me? I was using bitstrips.com for my previous comics. The tool is good but I don’t like the art that much. I prefer the xkcd style.
  • Or if you simply think that my comics suck, you can also let me know… So many years spent in academia made me sort of immune…

In any case, hope you enjoy it!

 

bookI have been working in this book for a while already. This is why I have been posting so much about Kivy lately and I will continue doing. The posts are a complement to the book and some very interesting ideas that I have learned during the process. It is also a way collaborate to the amazing job that Mathieu Virbel and his team are doing with this platform. And, of course, it is also a way to promote my book to recover the time investment made on it.

I have seen Kivy growing faster and faster, and I am positive that it will become a main competitor in the market of the mobile application development. As the second-last Twitter post says:

“How come #Kivy is not one of the most spoken about #Python projects? Cross-platform mobile app development in Python!”.

I cannot agree more. Kivy is still just being discovered and it’s simple fabulous. There are many good reasons to say that, but I will just highlight the ones that I consider most important, just in case you haven’t heard about it:

  1. It is cross platform. I haven’t found anything more compatible than Kivy. It runs in Linux, Windows, MacOSX, Android and IOS; and recently in Raspberry.
  2. Built-in interactivity. Many of the features you expect to see in a mobile application are ready-to-use in Kivy: multi-touch support, gestures, all sorts of keyboards, touch and clock events (including the magical Kivy properties), animations.
  3. It is Python. Ok, you may say this is a bit subjective. I have worked with Java, C++, PHP and others, and just a couple of years ago with Python. It does make a difference

It feels like a short and long process at the same. It was one year and a half ago when Mathieu wrote me about an already old post to help them with the documentation. I would have loved to participate but I was really busy with uni. However, when Pack Publishing contacted me because of exactly the same post (it is strange that somehow we hit the right spot on the internet and a post suddenly scale on searches, the post is quite bad to be honest but I was lucky), it was a very different scenario

This time I was quitting the university and just thinking to free lance and having a more formal blog. So, it just came on the right place and the story a success. The book is already available. I hope those that get to buy it, enjoy as much as I enjoy writing it.

I will continue doing Kivy posts. I hope more often now that the book is not sucking my time. Feel free to write me about any question related to the book or, well, anything in general. I have been also replying some questions in [StackOverflow](http://stackoverflow.com/users/1060349/toto-tico), so you can just post there were I frequently hang around.

As for today, I am glad of contributing with this great project. Thanks to the editorial and its team, and thanks to the Kivy team for this great library.

Long live to Kivy!

I have been insisting in the importance of PushMatrix and PopMatrix to control the use of the canvas in Kivy in:

In today’s post I explain a very specific example of how to rotate an Image without affecting the whole interface. I start with the common problem that the novice will experience and explain how to fix it:

 

1. The Initial Interface:

This is the screenshot of the interface we are going to work with. We want to rotate the image on the top-right of the layout.

GridLayout with one Button (top-left), one Image (top-right) and another Button (bottom-left)

This is the respective code:

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

Builder.load_string("""
<KivyImage@Image>:
    source: 'kivy.png'
    pos: self.parent.pos
    size_hint: .5,.4
    canvas:
        Color:
            rgba: 1,0,0,.5
        Line:
            rectangle: self.x, self.y, self.width, self.height

<TestApp>:
    cols: 2
    Button:
        text: "Place Holder 1"
    FloatLayout:
        KivyImage:
    Button:
        text: "Place Holder 2"
""")

class TestApp(App, GridLayout):
    def build(self):
        return self

if __name__ == "__main__":
    TestApp().run()

The interface is very simple. A GridLayout with 2 columns and 3 widgets. A Button (Place Holder 1), a FloatLayout with an Image inside and another Button (Place Holder 2). The FloatLayout contains the KivyImage class that we are going to be working with. The KivyImage also contains a rectangular border as a reference to follow our notations.

 

2. The Problem:

The instruction we need to use for rotating is Rotate. We use three parameters for it: axis that sets the axis are we going to use for the rotation, usually z since; angle that sets the amount of degrees we want to rotate. After using the Rotate instruction, our code will look like this:

<KivyImage@Image>:
    source: 'kivy.png'
    pos: self.parent.pos
    size_hint: .5,.4
    canvas:
        Rotate:
            axis: 0,0,1
            angle: 60
            origin: self.center
        Color:
            rgba: 1,0,0,.5
        Line:
            rectangle: self.x, self.y, self.width, self.height

Here is the result:

After the Rotation

As you can see, after applying the instruction, everything is rotated (including the last Button). This means, that when we use context instructions (Scale, Rotate and Translate), the whole coordinate space is affected.

More over, our image didn’t Rotate just the Rectangle!

 

3. Avoiding a global rotation:

We need to control the rotation, so the whole interface after the Rotate instruction is not affected. One way would be manually un-rotate with something like:

        Rotate:
            axis: 0,0,1
            angle: -60
            origin: self.center

Of course, that will be quite tedious. Instead, we are going to use two important instructions: PushMatrix, that saves the current context, and PopMatrix, that recovers the last saved context. Now the code looks like this:

<KivyImage@Image>:
    source: 'kivy.png'
    pos: self.parent.pos
    size_hint: .5,.4
    canvas:
        PushMatrix
        Rotate:
            axis: 0,0,1
            angle: 60
            origin: self.center
        Color:
            rgba: 1,0,0,.5
        Line:
            rectangle: self.x, self.y, self.width, self.height
        PopMatrix

And our new output should look like the following:

Using PushMatrix and Pop

Almost there, except that our images continues in the same original position. Let’s finally Rotate the image.

 

4. Rotate the image for once!:

Sorry, I tell you why the image is not rotated. In the 2nd step, even though the whole context where rotated, the image didn’t. The only explanation is that the Rotate where executed after the image is display on the screen.

Somehow, we need to guarantee that our Rotate instruction gets executed before. There is three sets of canvas instructions: canvas.before, canvas and canvas.after. Their names are intuitive, so let’s reorganize our instructions:

<<KivyImage@Image>:
    source: 'kivy.png'
    pos: self.parent.pos
    size_hint: .5,.4
    canvas.before:
        PushMatrix
        Rotate:
            axis: 0,0,1
            angle: 60
            origin: self.center
    canvas:
        Color:
            rgba: 1,0,0,.5
        Line:
            rectangle: self.x, self.y, self.width, self.height
    canvas.after:
        PopMatrix

And finally we got our image rotated without affecting the rest of the interface:

Rotated Image

It is not strictly necessary to move the PopMatrix to the canvas.after section. The difference would be in the children of the image. In this case, it doesn’t have. But in case it has children, then they will be rotated if the PopMatrix is in the canvas.after section.

Read more about the canvas in 10 things you should know about the Kivy canvas.