Reply to topic

[Tutorial] QML for Designers

User avatar alake
Registered Member
Posts
517
Karma
2
OS

[Tutorial] QML for Designers

Mon May 05, 2014 8:23 pm
Hello my fellow designers!

At Jens urging, I wanted to create a thread to share some QML knowledge in a tutorial format. I will start with the very basics to help you get oriented in QML land. I'll post a new entry to this thread everyday for about a week. In between I'm available to answer questions.

Jens and Uri from the core VDG team have volunteered to be the "main question makers" since they too have expressed an interest in learning QML. Of course, others with questions or with (more) QML expertise are certainly welcome to ask questions and provide answers as well.

Why should we as designers care about QML?
The main reason QML is useful to us is how immensely easy it is translate designs into something much more tangible. QML is also useful for developers since it can be used to fully implement the user interface layer for an application or idea. The visual design for both the Breeze widget style and the Breeze window decoration are implemented using QML. Ok, enough yammering. Let's get straight to it then.


Tutorial Post 1
For this first post let's get what we need to be able to follow along with this tutorial this week.
  1. You'll need Qt 5.1 or greater installed. Some recently released linux distros already have this installed or available in their software repositories. You can also download it from http://qt-project.org. It's also available for Windows and Mac if that's your preferred design environment... for now... :|
  2. You'll need Qt Creator. Again, this may already be available in in your linux distro software repositories. You can also download it from http://qt-project.org and it's also available for Windows and Mac. It is typically bundled with Qt 5.x so you can get them both as the same time if you want to.

If you have questions or need help getting those installed, ask here and help each other. Get those installed and ready to go. Tomorrow, around about this time, in Tutorial Post 2 I'll dig into implementing your first visual design in QML.
User avatar alake
Registered Member
Posts
517
Karma
2
OS

Re: [Tutorial] QML for Designers

Tue May 06, 2014 7:59 pm
Tutorial Post 2

Some content in this post is repetitive in relation to the excellent First Steps with QML tutorial provided by the Qt Project. I'l try to distill it down a bit though.

Open Qt Creator and create a new Qt Quick UI project.
  • Choose File > New File or Project
  • Make sure Applications is selected under Projects and select Qt Quick UI in the middle pane. Click the "Choose..." button.
  • Give your project a name "PictureEffects". Click "Next" for the next two pages then click "Finish".

You'll now have a PictureEffects.qml file with the following qml :
Code: Select all
import QtQuick 2.0

Rectangle {
    width: 360
    height: 360
    Text {
        anchors.centerIn: parent
        text: "Hello World"
    }
    MouseArea {
        anchors.fill: parent
        onClicked: {
            Qt.quit();
        }
    }
}


The qml code is pretty easy to read, so I'll go through and explain it:
  • "import QtQuick 2.0" is needed to do basic QML stuff. Just make sure this is always in you .qml file and don't worry about it.
  • The rest is basically saying display a 360x360 rectangle with the text "Hello World" centered in it.
  • That MouseArea thing basically says quit the app when anywhere in the Rectangle is clicked. Don't worry too much about this for now.
If you want to see what it looks like, choose Build > Run, or click the big green arrow to the lower left.

So the Rectangle element is one of the most frequently used elements so let's dig into it a little. There are a lot of things you can do with the Rectangle element. You can change the size, the color, add a corner radius, add a gradient, add a border, change the border thickness, change the border color and much more. The Qt project has an excellent guide for [url]every QML element[/url]. Check out the guide for the Rectangle element.

Here's a Rectangle that (roughly) approximates the look of the visual design of our button control that we did recently:
Image
Code: Select all
Rectangle {
    height: 32
    width: 96
    radius: 3
    border.width: 1
    border.color: "#5531363b"
    color: "#eff0f1"
}


Cut and paste the above rectangle element into your PictureEffects.qml file below the Text element. You PictreEffects.qml file should look like this:
Code: Select all
Rectangle {
    width: 360
    height: 360
    Text {
        anchors.centerIn: parent
        text: "Hello World"
    }
    Rectangle {
        height: 32
        width: 96
        radius: 3
        border.width: 1
        border.color: "#5531363b"
        color: "#eff0f1"
    }
    MouseArea {
        anchors.fill: parent
        onClicked: {
            Qt.quit();
        }
    }
}

Click Run to see what it looks like. Play around with the newly added Rectangle element in your PictureEffects.qml file. Here are a few things to be aware of while you're playing around:
  • There can only be one root element. So to add another rectangle element or text element is must be contained in the root Rectangle element.
  • The elements are stacked on top of each other in the order they appear within the same scope (same parent element).
Check out the the Qt Project guide for the Rectangle element and try to add a gradient. Try to center the new rectangle like the Text element is. Try to make the text appear on top on the new rectangle. Fiddle away!

One last thing I wanted to quickly mention is anchors. Notice the Text element has "anchors.centerIn: parent" property. Anchors are a way to position/size an element relative to another element. See the Qt Project Guide on the many kinds of anchors. Just remember this:
  • Margin anchors need their corresponding logical anchor property to be set. For example, for anchors.leftMargin to work it needs anchors.left or anchors.fill to be set.
  • Offsets need their corresponding logical anchor property to be set. For example, for anchors.verticalCenterOffset to work it needs anchors.verticalCenter to be set.
  • Anchors can effectively define the width and height. For example, "anchors.fill: parent" basically makes the element width the height the same as the parent (assuming no margin is set).

Try fiddling with the anchors property in either the Text element or the new Rectangle element. Don't worry if you don't get it all right away. We'll have plenty of opportunity to use it.

So what's next? And why did we name the project "PictureEffects" anyway? Well we have the basics we need to do this:
Image

Good luck and see you next post!
User avatar jensreuterberg
Registered Member
Posts
590
Karma
3
OS

Re: [Tutorial] QML for Designers

Tue May 06, 2014 8:51 pm
The student is in and is sitting down with things as we speak. No questions yet but they will soon come

Image


KDE Visual Design Group - "Sexy by default - Powerful through cooperation"
User avatar Uri_Herrera
Registered Member
Posts
194
Karma
0
OS

Re: [Tutorial] QML for Designers

Tue May 06, 2014 10:08 pm
Well.. I don't even know where to start. I'll do some icons while I think of questions.
davidwright
Registered Member
Posts
151
Karma
0
OS

Re: [Tutorial] QML for Designers

Tue May 06, 2014 10:35 pm
One question (not about the two chapters though, so I hope that's ok :P ). Once plasma next ships, how would I write a vanilla qml app so that it would use the breeze style for it's buttons etc? Will KDE automatically theme it? Or will you have to do an 'import Breeze' or something?
User avatar donniezazen
Registered Member
Posts
109
Karma
0
OS

Re: [Tutorial] QML for Designers

Wed May 07, 2014 2:11 am
Are you targeting programmers or absolute beginners? Should I know some programming or particular programming language to understand these?

PS:- I know Java and have started learning C++.
Sogatori
Registered Member
Posts
194
Karma
0
OS

Re: [Tutorial] QML for Designers

Wed May 07, 2014 3:34 am
It worked! I feel like the uber hacker already :D
User avatar jensreuterberg
Registered Member
Posts
590
Karma
3
OS

Re: [Tutorial] QML for Designers

Wed May 07, 2014 7:30 am
Donniezazen: this is mostly for noobs like me - but anyone can join! :)


KDE Visual Design Group - "Sexy by default - Powerful through cooperation"
User avatar Uri_Herrera
Registered Member
Posts
194
Karma
0
OS

Re: [Tutorial] QML for Designers

Wed May 07, 2014 7:33 am
Ok.. well I have added a button succesfully.. :D now, how do I move it around? with anchors right? ??? .. and how to I make it not close on click .
Sogatori
Registered Member
Posts
194
Karma
0
OS

Re: [Tutorial] QML for Designers

Wed May 07, 2014 8:24 am
Uri_Herrera wrote:Ok.. well I have added a button succesfully.. :D now, how do I move it around? with anchors right? ??? .. and how to I make it not close on click .

I'm still figuring out myself, but anchors seem to do most of the positioning stuff. By deleting the "MouseArea" property the window should not close when you click anywhere within the root item.
User avatar Heiko Tietze
Registered Member
Posts
452
Karma
0
OS

Re: [Tutorial] QML for Designers

Wed May 07, 2014 8:44 am
I face the issue that 'no active kit is available', irrespective from the qt version. Thus my triangle is not green and I cannot test the code. Qt5 is installed (Arch Linux) but kit settings show 4.8.5 only. What's wrong?

PS: Easy to solve: Go to settings, tab Qt-versions and select from /usr/bin qmake-qt4 and qmake-qt5. And arrows become green. :-)
User avatar alake
Registered Member
Posts
517
Karma
2
OS

Re: [Tutorial] QML for Designers

Wed May 07, 2014 4:32 pm
Uri_Herrera wrote:Ok.. well I have added a button succesfully.. :D now, how do I move it around? with anchors right? ??? .. and how to I make it not close on click .


Yes, you can position elements relatively to other elements with the anchors property. You can give any element a name using the "id" property. For example you can name the new Rectangle element "background" by adding an "id" property like this:
Code: Select all
    Rectangle {
        id: background
        height: 32
        width: 96
        radius: 3
        border.width: 1
        border.color: "#5531363b"
        color: "#eff0f1"
    }

Then you can center the text in the "background" element like so:
Code: Select all
Rectangle {
    width: 360
    height: 360
    Rectangle {
        id: background
        height: 32
        width: 96
        radius: 3
        border.width: 1
        border.color: "#5531363b"
        color: "#eff0f1"
    }
    Text {
        anchors.centerIn: background
        text: "Button"
    }
}

Note that you can always reference the parent of any element by using "parent", even if it doesn't actually have "id" property set. So if you put the Text element in the new Rectangle, you can refer to the new Rectangle as "parent" even if it doesn't have and "id" property set. Like so:
Code: Select all
Rectangle {
    width: 360
    height: 360
    Rectangle {
        height: 32
        width: 96
        radius: 3
        border.width: 1
        border.color: "#5531363b"
        color: "#eff0f1"
       
        Text {
            anchors.centerIn: parent
            text: "Button"
        }
    }
}


If you want to want to position something absolutely (not relative to other elements) you can use the x and y property. For example, adding "x: 100" and "y: 100" to any element will position it 100 pixels to the left and 100 pixels down. The origin is the top, left corner of it's parent element and y is positive in the down direction.

We'll rarely use absolutely positioning, favoring anchors instead, but it can sometimes come in handy in a pinch. :-)

Oh and yes, like others have pointed out, just remove the MouseArea element to prevent it from closing when you click it.
User avatar alake
Registered Member
Posts
517
Karma
2
OS

Re: [Tutorial] QML for Designers

Wed May 07, 2014 10:02 pm
Tutorial Post 3

Let's say we were asked to design the interface for a very simple picture effects app that basically allows the user to load an image, tint it a particular color and save the tinted image. So we came up with a visual design and did a mockup of it:
Image

Let's see how we might implement this mockup in QML.

First we'll make a few modifications to our PictureEffects. qml to remove that new rectangle we added and the text, leaving us with an empty rectangle to start with. Let's also make the width smaller than the height, similar to our mockup. The resulting PictureEffects.qml should look similar to this:
Code: Select all
import QtQuick 2.0

Rectangle {
    width: 300
    height: 360
}

By default the Rectangle color is white. We want the background to be the window background color. You could load up your system setting to see the curent color scheme, look for the window background color and paste that color value here. But you don't have to. Qt Quick provides an easy way to access the system color palette directly and get the window background color!
Code: Select all
import QtQuick 2.0

Rectangle {

    SystemPalette { id: myPalette; colorGroup: SystemPalette.Active }

    width: 300
    height: 360
    color: myPalette.window
}

SystemPalette is an element you can use to access the system color palette. In this case we named the SystemPalette element "myPalette" using the "id" property so we can reference it later. Now we can set the color of the rectangle using myPalette instead of a hard-coded color. Since there are many colors in the system palette (background color, text color, highlight color, etc.) we just need to say which color from the palette we want to use. In this case we want to use the window background color so we say "color: myPalette.window". How easy is that?!

Let's start laying things out. Looking at the mockup, there are roughly two areas in the design; the upper area containing the picture and the lower area containing the controls. So lets add two rectangles for those two areas.
Code: Select all
import QtQuick 2.0

Rectangle {

    SystemPalette { id: myPalette; colorGroup: SystemPalette.Active }

    width: 300
    height: 360
    color: myPalette.window

    Rectangle {
        id: controls
        anchors.left: parent.left
        anchors.leftMargin: 8
        anchors.right: parent.right
        anchors.rightMargin: 8
        anchors.bottom: parent.bottom
        anchors.bottomMargin: 8
        height: 60
    }

    Rectangle {
        id:pictureHolder
        anchors {
            top: parent.top
            left: parent.left
            right: parent.right
            bottom: controls.top
            margins: 8
        }
        color: "#55000000"
        radius: 4
        }
    }
}

We added a rectangle named "controls" whose left, right and bottom edges are anchored to the corresponding edges of the parent rectangle. It also has an 8 pixel margin on the left, right and bottom edges. I often try to place the margin property next to it's corresponding logical anchor so I remember to always have both. We also set the height of the "controls" rectangle to 60 pixels. Why didn't we set the width?! That's because anchors for the left and right edges of the rectangle effectively define the width, so there's no need to specify a width. :-)

We also added a rectangle named "pictureHolder". Notice its top, left and right edges are anchored to the corresponding edges of it's parent, but the bottom edge is anchored to the top of the "controls" rectangle. Notice also that you can specify the anchors in a group (using the curly braces) instead of always typing out "anchors.top", "anchors.left", etc. like we did in the "controls" rectangle. We also set the margins to 8 pixels. If all the margins are the same you can just set the "anchors.margins" property instead of specifying each margin with "anchors.leftMargin", "anchors.topMargin" and so on. We also gave it a corner radius of 4 pixels and set the color to "#55000000" (black with an alpha so the background of the parent rect shows through).

Now lets add a picture to the picture holder. Qt Quick provides an Image element for this. So we will add it to the picture holder to match what we have in the mockup:
Code: Select all
import QtQuick 2.0

Rectangle {

    SystemPalette { id: myPalette; colorGroup: SystemPalette.Active }

    width: 300
    height: 360
    color: myPalette.window

    Rectangle {
        id: controls
        anchors.left: parent.left
        anchors.leftMargin: 8
        anchors.right: parent.right
        anchors.rightMargin: 8
        anchors.bottom: parent.bottom
        anchors.bottomMargin: 8
        height: 60
    }

    Rectangle {
        id:pictureHolder
        anchors {
            top: parent.top
            left: parent.left
            right: parent.right
            bottom: controls.top
            margins: 8
        }
        color: "#55000000"
        radius: 4

        Image {
            source: "flowers.jpg"
            anchors {
                fill: pictureHolder
                margins: 4
            }
        }
    }
}

Just like the rectangle element, you can use anchors to position the image. The "anchors.fill" property is just shorthand for telling it to anchor the left, right, top and bottom edges to the corresponding edges of the named element, in this case the "pictureHolder" rectangle. Since the "pictureHolder" is also the parent of the Image element, you could also say "fill: parent" and the result would be the same. We also set a margin of 4 pixels so you can see the "pictureHolder" around the edges of the picture. But what about that "source" property? That just says what the source of the image should be. Find a picture you like, copy it into the same folder as PictureEffects.qml and set the "source" property to the filename of the picture file. Easy as pie!

Next time we'll start adding the controls to the "controls" rectangle. Till then, try positioning the "controls" rectangle to the top edge of the picture holder. Or maybe try increasing the grey area around the picture. Or maybe picking a different color from the system palette. Look at the Qt Project guide for these elements and play around a bit! Have fun!
User avatar alake
Registered Member
Posts
517
Karma
2
OS

Re: [Tutorial] QML for Designers

Wed May 07, 2014 10:52 pm
davidwright wrote:One question (not about the two chapters though, so I hope that's ok :P ). Once plasma next ships, how would I write a vanilla qml app so that it would use the breeze style for it's buttons etc? Will KDE automatically theme it? Or will you have to do an 'import Breeze' or something?


Sorry I didn't answer this earlier davidwright. If it's not too much trouble, could you post this question on the Qt Quick Controls thread, or send me a message here or on Google+ and I'd be happy to answer it. :-)
User avatar Darshak
Registered Member
Posts
1
Karma
0

Re: [Tutorial] QML for Designers

Wed Aug 06, 2014 12:19 pm
Hi there Andrew! It was only now that I came across this great tutorial, and I must say, it's very well written and easy to follow. So, could you tell me if there are plans to continue this? (Or perhaps, has it moved elsewhere?)

Thank you. :)

 
Reply to topic

Bookmarks



Who is online

Registered users: Baidu [Spider], Bing [Bot], boudewijn, Exabot [Bot], Google [Bot], koriun, paulus3005, sdh, sinclair, Sogou [Bot], TheraHedwig, tokiedian, vpinon, Yahoo [Bot]