Sunday, February 13, 2011

Second QML Tutorial

Hi everybody,

Here is finally the second QML tutorial! Before starting, I hope you are all ok with the first tutorial, I hope you remember the first application with the circles. If not, you can find the link to the tutorial on the menu on your right.

So, now that you remember, you can see that several pieces of code have been repeated. Let’s have an example:
Rectangle{
    id: happy_circle_green
    x: 271
    y: 72
    width: 63
    height: 63
    radius: width/2
    color: "lightgreen"
}
As you already noticed, they all have the same properties, only the value is changing. However, this is not nice to write them all like a long list. This is not very efficient. A good design idea is to make things reusable. Then it’s more efficient, and you can even share components between applications when it’s possible.

Let’s create a new application called Second Tutorial. In your application folder, please add a file called Circle.qml. The capital letter at the beginning might look useless but it is said in the documentation that it’s a good practice and I actually like it like this. Also, regarding naming, here is another good practice: NO SPACE in file names. It’s better to use the underscore character.

Ok, so back to our new file, we can put the following code in it:
import QtQuick 1.0

Rectangle{
    id: circle_root

    property int posX: 0
    property int posY: 0
    property int size: 200
    property string selectedColor: "black"

    x: posX
    y: posY
    width: size
    height: size
    radius: size/2
    color: selectedColor
}
As you can see, I’m using a new important thing: the property keyword. This allows us to have generic properties which can be used all over the file or also accessed from another file. In this case I gave fixed values to make things go step by step. So if you try to display it, this will look like this:

Well, that’s a good start. Now, let’s play with that. Since the file is in the same folder it is automatically recognized within any other QML file from the same folder. Let’s put this in an application:
import QtQuick 1.0

Rectangle {
    id: tuto_root

    width: 360
    height: 360
    color: "darkgrey"

    Circle {
        id: tuto_first_circle
    }

    MouseArea {
        id: tuto_msa
        anchors.centerIn: parent
        onClicked: {
            Qt.quit();
        }
    }
}
This gives us :

Ok, I said, we can play with it… and I also said we can access these properties from the outside. Let’s do it. I want a smaller circle e.g. diameter = 100, with a blue color and at position (20,150). Here is the code; I think you can understand easily:
import QtQuick 1.0

Rectangle {
    id: tuto_root

    width: 360
    height: 360
    color: "darkgrey"

    Circle {
        id: tuto_first_circle
        selectedColor: "blue"
        posX: 20
        posY: 150
        size: 100
    }

    MouseArea {
        id: tuto_msa
        anchors.centerIn: parent
        onClicked: {
            Qt.quit();
        }
    }
}
Well, so far so good, I guess you understand how we can play with the properties

These properties are really useful. In the current case, this is more like creating a variable. These variables are assessed to some properties to make them change either easily (e.g. size is used for 3 properties) and/or from the outside (as we did when we integrated the circle in the main app). In this case, I set a default value for the properties. You don’t have to, but I recommend you to do it.

There is also another kind of property: the alias. An alias allows you to refer to the value of a field in a more generic way. The following code does exactly the same thing as before:
import QtQuick 1.0

Rectangle{
    id: circle_root

    property int posX: 0
    property int posY: 0
    property int size: 200
    property alias selectedColor: circle_root.color

    x: posX
    y: posY
    width: size
    height: size
    radius: size/2
}
Let’s say, right now, the difference might seem quite light, but when you will be playing more with QML you will see what suits the best for you. Anyway, we now have a reusable component. This is very interesting because QML provides components to create a bunch of components easily. For example, we can use a Repeater component within a Row component to generate a row of circle. Here is the code:
import QtQuick 1.0

Rectangle {
    id: tuto_root

    width: 360
    height: 360
    color: "darkgrey"

    Row {
        id: tuto_row
        Repeater {
            id: tuto_repeater
            model: 5
            Circle {
                id: tuto_first_circle
                selectedColor: "blue"
                size: 360 / tuto_repeater.model
            }
        }
    }

    MouseArea {
        id: tuto_msa
        anchors.centerIn: parent
        onClicked: {
            Qt.quit();
        }
    }
}
And the result:

As you can noticed, I reuse also the model property from the Repeater to adjust the size of the circle to the width of the window regarding the number I want. Quite easy, isn’t it?
That’s enough for today, I advise you to play with the properties, to play also with the Repeater component. For more details on this component, go here.

Have fun!

3 comments:

  1. Hi,

    Thanks for the great tutorials. I really like that you go slowly and give explanations for why you do things.

    If you make more tutorials, could you do one about integrating with javascript and possibly c++?

    Thanks and keep up the good work.

    ReplyDelete
  2. Hi Shafqat, thanks for enjoying my tutorials haha :D and of course, i plan to do more tutorials and to talk about integrating some Javascript and why not C++ (but this is already way more advanced).

    ReplyDelete
  3. Very nice tutorial.......
    It'll be a lot of help if u post a tutorial on states and animations.
    I really like QML......

    ReplyDelete