Qml QtQuick Essentials Training
3-day session

 
Overview
Qt Quick scene graph concept
Understanding Qml Component/Document/Module Architecute
Understanding QtQuick classes
Exporting C++ class to Qml as object and class type
Three layers software development with qml and c++
Dynamic Properties
Duration
Three days - 24 hours
50% of lecture, 50% of practical labs.
Trainer

Prerequisite
Knowledge of Qt programming
Knowledge of Qt programming is important. Technically Qml is javascript
counter part of C++ Qt. Knowing Qt will help fast understanding of Qml.
Qt slides can browsed at
http://www.minhinc.com/training/qt/advance-qt-slides.php

Pdf document can be downloaded from
http://www.minhinc.com/training/advance-qt-slides.pdf

Knowledge of GUI and other concepts
Qt/Qml is used for GUI development and many other technologies including 
Networks, operating systems, Database, scripting. Basic knowledge of these domains 
are required as per the Qt/Qml is developed for the particular domain.

Setup
Ubuntu LTS 16.04, Qt 5.[>6]
© www.minhinc.com
p1
Lecture
Lecture session will be course content presentation through the trainer.
Any source code example related to the topic will be demonstrated, it would
include executing the binaries. Lecture content can be downloaded at 
http://www.minhinc.com/training/advance-qml-slides.pdf
Labs
Labs session would be completely hands on session where each example (with
example data and execution instruction) would be provided to the students. Students
can verify their results with the results provided in the material.
Day 1 Morning

© www.MinhInc.com
p2
Day 1 Afternoon

     Lab
Day 2 Morning

© www.MinhInc.com
p3
Day 2 Afternoon

     Lab
Day 3 Morning

Day 3 Afternoon

© www.MinhInc.com
p4
     Lab
 
Day 1 Morning
  1. Introduction to Qt Quick and QML
QObject has two parts
One is QObject declared in class and another is meta object associated to the QObject. Meta Object is referred by QMetaObject. Methods in meta object is referred by QMetaProperty.

QMetaObject *mo=::QObject->metaObject();
Meta object property can be executed through QObject as
::QObject->setProperty("abc",20);
                  +------------------+
                  |                  |
+-----------------|----+   +---------|-------------------+
|                 |    |   |         |                   |
|                 |                  |                   |
|      QObject    |   QMetaObject    |  Qml Framework    |
|                 |                  |                   |
|                 |                  |                   |
|                 |    |   |         |                   |
|                 |    |   |         |                   |
+-----------------|----+   +---------|-------------------+
                  |                  |
                  +------------------+
                        ^
                        |
                        +--- QMetaObject shared by C++ and QML sides 

const QMetaObject* metaObject=obj->MetaObject();
QStringList properites;
for(int i = metaObject->propertyOffset();i<metaObject->propertyCount();++i)
properties<<QString::fromLatin1(metaObject->property(i).name());

A Property can be added to meta system through
Q_PROPERTY(type name
            (READ getFunction [WRITE setFunction] |
             MEMBER memberName [(READ getFunction | WRITE setFunction)])
            [RESET resetFunction]
            [NOTIFY notifySignal]
            [REVISION int]
            [DESIGNABLE bool]
            [SCRIPTABLE bool]
            [STORED bool]
            [USER bool]
            [CONSTANT]
            [FINAL])
class Person : public QObject
{
 Q_OBJECT
 Q_PROPERTY(QString name READ name WRITE setName)
 Q_PROPERTY(int shoeSize READ shoeSize WRITE setShoeSize)
 .
 .

A methods can be added to meta system by
Q_INVOKABLE

class Window:public QWidget{
Q_OBJECT
public:
 Window();
 void normalMethod();
 Q_INVOKABLE void invokableMethod();
};

Day 1 Morning
  1. Introduction to Qt Quick and QML
A .qml file is a component which is similar to a c++ header file having single
 class declration. A Qml component can exist as a .qml file/document or can be embedded in a Qml document. 

Qml file contains 
a) A import statement (not exatly same as c/c++ incude directive)
© www.minhinc.com
p5
b) A single root obect delcraton (Item or its deriviative)

- import statement is to provides modules or type namespaces or javascript
 to enable the engine to load the QML Object types referenced within the
 doucment. Its not copy paste like #include in c/C++

- qml object describes the hierarchy of single object wich can be inherited,
 etended and instantiated. So it can have single root object hierarchy only. 
Once qml file in this fasion becomes a library object With new set of 
properties that can be resused in other component.

So one qml file creates one component or one new type that is resusable.  
Base class of all qml type is "Item"
Item instantiates C++ class QquickItem
                      -------------------
                      |Item : QQuickItem|
                      -------------------
                              .
                             / \
                              -
                              |
  +--------+---------+--------------------+-------------+
  |        |         |                    |             | 
  -------- --------- ----------- ----------- -------------
  |Column| |Control| |Rectangle| |TextInput| |StackLayout| . . .
  -------- --------- ----------- ----------- -------------
              .
             / \
              -
              |
  +------------+---------+--------------------+
  |            |         |                    |
  ---------- --------- ---------- ----------- ------
  |Abstract| |BusyInd| |ComboBox| |Container| |Pane| . . .
  |Button  | |icator | ---------- ----------- ------
  ---------- ---------               .           .
       .                            / \        / \ 
      / \                           -           -
       -
       |                             |           |
       |    +------------------------+  +-----------------------+
       |    |           |            |  |           |           |
       | --------- ----------- -------- ------- ------ ------------
       | |MenuBar| |SwipeView| |TabBar| |Frame| |Page| |ScrollView|..
       | --------- ----------- -------- ------- ------ ------------
       |
  +------------+---------+--------------------+
  |            |         |                    |
  -------- ---------- ------------- --------------
  |Button| |CheckBox| |DelayButton| |ItemDelegate|..
  -------- ---------- ------------- --------------
 // MyQmlFile.qml
 import QtQuick 2.0
 Rectangle { width: 200; height: 200; color: "red" }
 Rectangle { width: 200; height: 200; color: "blue" } // invalid two root object

Creating new Button type
  // Button.qml
 import QtQuick 2.0
 Rectangle {
  width: 100; height: 100
  color: "red"
  MouseArea {
   anchors.fill: parent
   onClicked: console.log("Button clicked!")
  }
 }

The Button type can then be used in an application:
  // application.qml
 import QtQuick 2.0
 Column {
  Button { width: 50; height: 50 }
  Button { x: 50; width: 100; height: 50; color: "blue" }
  Button { width: 50; height: 50; radius: 8 }
 }

          -------------------
          |Item : QQuickItem|
          -------------------
                 .
                / \
                 -
© www.minhinc.com
p6
                 |
            -----------
            |Rectangle|
            -----------
                 .
                / \
                 -
                 |
            -----------
            | : Button| // Button inherits Rectangle in Button.qml and
            ----------- // gets instantiated in application.qml

A component can exist in a qml directory like 
a)
import QtQuick 2.0
Item {
 width: 100; height: 100
 Component {
  id: redSquare
  Rectangle {
   color: "red"
   width: 10
   height: 10
  }
 }
 Loader { sourceComponent: redSquare }
 Loader { sourceComponent: redSquare; x: 20 }
where id is extra provided than file component 
b) 
var component = Qt.createComponent("Button.qml");
 if (component.status == Component.Ready)
  component.createObject(parent, {"x": 100, "y": 100});

c)
Item {
 id: root
 width: 500; height: 500
 Component {
  id: myComponent
  Rectangle { width: 100; height: 100; color: "red" }
 }
 Component.onCompleted: {
  myComponent.createObject(root)
  myComponent.createObject(root, {"x": 200})
 }
}

Day 1 Morning
  1. Introduction to Qt Quick and QML
.qml file contains root Qml object (QQuickItem) where other sub objects aligned in parent child relationship making tree of objects. child objects are assigned to some property value of the parent object. Subobjects not assigned to parent's any property goes to parent default property.
for ex. xyz.qml
<Xyz.qml>
       Rectangle <>----+
                       |
                       |
                       |
                       |--> Rectangle
                       |--> TextArea 
                       |--> TextInput
                       |--> QTimer
                       |--> Text
In this case Xyz is a new type that derived from Rectangle.
         Rectangle
            .
           / \
           ---
            |
           Xyz

© www.minhinc.com
p7
Day 1 Morning
  1. Introduction to Qt Quick and QML
Qml has mainly two types
Basic types-
bool, double, enumeration, int ,list, real, string, url, var
Object Types Non Gui Types-
QtObject, Connection, Component, Timer
QtQuick Gui Types-
Item, Rectangle, TextArea, Text, TextInput
Basic types Basic types does not need any module to be imported by 'import' keyword. Basic type provided through QtQuick module date point, rect and size 'Qt' which is global variable provides subroutines to manipulate the basic types For basic type, property change signal handler is invalid whereas signal handler on basic type itself is valid
Text {
// invalid!
 onFont.pixelSizeChanged: doSomething()
// also invalid!
 font {
  onPixelSizeChanged: doSomething()
 }
 onFontChanged: console.log("font changed")

 id: otherText
 focus: true
 Keys.onDigit1Pressed: font.pixelSize += 1
 Keys.onDigit2Pressed: font.b = !font.b
 Keys.onDigit3Pressed: font = otherText.font
}

javascript objects and arrays are also supported
with keyword 
var
.
Date
and
Array
functors are available in Qml
import QtQuick 2.0
Item {
 property var theArray: new Array()
 property var theDate: new Date()
 Component.onCompleted: {
  for (var i = 0; i < 10; i++)
   theArray.push("Item " + i)
  console.log("There are", theArray.length, "items in the array")
  console.log("The time is", theDate.toUTCString())
 }
}

Types in Qml comes from three sources
a)Provided natively by qml compiler
b)Registered via c++ by QML modules
c)Provided as QML documents by QML module

Object type
All object types are derived from 
QtQObject
      QObject
        .
       / \
        -
        |
   Qml Object Type

custom types can be made trough qml document types

Non gui Object types comes from QtQml module
Component Date, Number, String, Component, Qt,QtObject, Locale, Binding, Connections, Instantiator, Timer

© www.minhinc.com
p8
List, Model Qml object types from QtQml.Model module
DelegateModel, DelegateModelGroup, ListElement, ListModel, ObjectModel

Whereas GUI object types come from QtQuick module
Day 1 Morning
  1. Introduction to Qt Quick and QML

Qt Quick QML Types provided through QtQuick import
-
XML List Model
-
Local Storage
- submodule containing javaScript interface for an SQLite database -
Particles
- provides a particle system for Qt Quick -
Layouts
- provides layout for arranging Qt Quick items -
Window
- top-level windows and accessing screen information -
Dialogs
- creating and interacting with system dialogs -
Tests
- unit test for a QML application -
Controls
- set of reusable UI componets
© www.minhinc.com
p9
 
Day 1 Morning
  2. Qt Properties

Get, Set and Notify are getter, setter and setter notification signal function addition to Meta Object System. A new property is introducted in Meta Object System which is visible on QML side. Same thing can be achieved on Qml side when a new property and assiciated functions gets added to Meta Object System. As per Qml design those property as visible on C++ side also and signal handler to signal added in Qml side can be introduced in C++ side.

class Message : public QObject
{
 Q_OBJECT
 Q_PROPERTY(QString author READ author WRITE setAuthor NOTIFY authorChanged)
public:
 void setAuthor(const QString &a) {
  if (a != m_author) {
   m_author = a;
   emit authorChanged();
  }
 }
 QString author() const {
  return m_author;
 }
 signals:
  void authorChanged();
 private:
  QString m_author;
};

Here whenever author is modified in QML side, authorChanged signal is emitted. Qml engine attache a empty signal handler for it, named 'onAuthorChanged' in template on<propertyname>Changed.

This can be added to qml meta object system as object type or as instantiated object.

Instantiated object
int main(int argc, char *argv[]) {
 QGuiApplication app(argc, argv);
 QQuickView view;
 Message msg;
 view.engine()->rootContext()->setContextProperty("msg", &msg);
 view.setSource(QUrl::fromLocalFile("MyItem.qml"));
 view.show();
 return app.exec();
}

// MyItem.qml
import QtQuick 2.0
Text {
 width: 100; height: 100
 text: msg.author    // invokes Message::author() to get this value
 Component.onCompleted: {
  msg.author = "Jonah"  // invokes Message::setAuthor()
}
}

Registrered type
main(.....){
...
qmlRegisterType<Message>("Messaging", 1, 1, "Message")
...
}
// MyItem.qml
import QtQuick 2.0
import Messaging 1.1
Text {
 width: 100; height: 100
 Component.onCompleted: {
  text: Message{
   author="Jonah"
  }
 }
}

© www.minhinc.com
p10

 
Day 1 Morning
  2. Qt Properties

An object can have following attributes
a) The id attribute
b) property attributes
c) signal attributes
d) signal handler attributes
e) method attributes
f) attached properties and attached signal handler attributes

a) The id attrubute 
The id attribute is unique for each instance of the class and it must start with lower case. Id is "component scoed". Id can be used to idenify the object as 
if it is object name.
import QtQuick 2.0
 Column {
  width: 200; height: 200
  TextInput { id: myTextInput; text: "Hello World" }
  Text { text: myTextInput.text }
 }

b) property attributes
Qml has baisc types and object types. Object types can have property value that is static in value or bound to dynamic expression.

1) Defining property
 A proprty can be inserted in QML object type through adding Q_PROPERY on C++ couter part class.
2) A property can be inserted in QML object through adding 
'[default] property <propertyType> <propertyName>'
ex.
 Item {
//Basic types
  property int someNumber
  property string someString
  property url someUrl
//Var is takes any kind
  property var someNumber: 1.5
  property var someString: "abc"
  property var someBool: true
  property var someList: [1, 2, "three", "four"]
  property var someObject: Rectangle { width: 100; height: 100; color: "red" }
//Object type
  property Item someItem
  property Rectangle someRectangle
  property color nextColor: "blue" // declaration and initialization
//Custom type
  Property BasicButton bbtn // BasicButton.qml exists
 }

Property binding does not work on staticvalue returned through Javascript statement
import QtQuick 2.0
Rectangle {
 width: 100
 height: width * 2
 focus: true
 Keys.onSpacePressed: {
  height = width * 3 // once come here height is frozen
 }
}

Qt.binding() should be used instead
import QtQuick 2.0
Item {
width:500;height:500
Rectangle{
 id:rect
© www.minhinc.com
p11
 width:100;  height:width*2
 focus:true
 Keys.onSpacePressed:{
  rect.height=Qt.binding(function() {return this.width*3})//'this' is component 
                                                          // not rect
 }                                                // this must be in Qt binding
}
3) property alias
Property alias is used to create alias to other property similar to reference in C++. It is mostly used in component property making alias to child items property. While creating object type only component level properties are visible outside.

       +------------------------+
       | Rectangle {            |
       |property alias bx x.text|-------o 
       +---------------|--------+       \
       |               |        |        .... component bx actually
       |  Text {       |        |        referring to child Text.text
       |   id x <------+        |
       |  }                     |
       | }                      |
       +------------------------+
           Button.qml
  [default] property alias <name>: <alias reference>

// Button.qml
import QtQuick 2.0
Rectangle {
property alias buttonText: textItem.text
width: 100; height: 30; color: "yellow"
Text { id: textItem }
}

Now Button.qml can be used in other qml document as
Button { buttonText: "Click Me" }

4) List property
List of valus can be declared as 
[default] property list<<objectType>> propertyName: <value>
<<MyRectangle.qml>>
import QtQuick 2.0
Rectangle {
// declaration without initialization
 property list<Rectangle> siblingRects
// declaration with initialization
property list<Rectangle> childRects: [Rectangle { color: "red" },Rectangle { color: "blue"} ]
}

5) Grouped property
class member of  object type can be field inititalized in curly braces
Text {
//dot notation
 font.pixelSize: 12;; font.b: true
}

font object properites can be grouped in curly braces
Text {
//group notation
font { pixelSize: 12; b: true }
}

4) Default property
Default property come into the picture when a object type is getting instantiated in a parent object type without gettig assigned to any of the parent properties. In this fashon parent default property holds the children.

c) Signal property
Signal is function that gets rasied by hardware or just by calling the function. Like unix signal, qml signal has handler associated to it.
signal can be declared as 
  signal <signalName>[([<type> <parameter name>[, -]])]
<MySignal.qml>
import QtQuick 2.0
Item {
 signal clicked // with no argument, braces are not required
 signal hovered()
 signal actionPerformed(string action, var actionResult)
}

© www.minhinc.com
p12
d)signal handler property
Qml also supports inbuilt handler for properites in the format "on<Property>Changed"
<<MyTextInput.qml>>
import QtQuick 2.0
TextInput {
 text: "Change this!"
 onTextChanged: console.log("Text has changed to:", text)
}

Signal handler must be in nomenculture on<SignalName> or any method can also be nominated as signal handler.
<SquareButton.qml>
Rectangle {
id: root
signal activated(real xPosition, real yPosition)
signal deactivated
property int side: 100
idth: side; height: side
MouseArea {
anchors.fill: parent
onPressed: root.activated(mouse.x, mouse.y)//handler has not arguments declaration explictly
onReleased: root.deactivated()
}
}

class method can also be used as signal hander
Rectangle {
id: relay
signal messageReceived(string person, string notice)
Component.onCompleted: {
relay.messageReceived.connect(sendToPost)
relay.messageReceived.connect(sendToTelegraph)
relay.messageReceived.connect(sendToEmail)
relay.messageReceived("Tom", "Happy Birthday")
}
function sendToPost(person, notice) {
console.log("Sending to post: " + person + ", " + notice)
}
function sendToTelegraph(person, notice) {
console.log("Sending to telegraph: " + person + ", " + notice)
}
function sendToEmail(person, notice) {
console.log("Sending to email: " + person + ", " + notice)
}
}

e) Mehtod property
In c++ counterpart method can be declared through Q_PROPERTY() and Q_SLOT() for slots. In qml it through
function <functionName>([<parameterName>[, ...]]) { <body> }
<<MyText.qml>>
import QtQuick 2.0
Item {
width: 200; height: 200
MouseArea {
anchors.fill: parent
onClicked: label.moveTo(mouse.x, mouse.y)
}
Text {
id: label
function moveTo(newX, newY) {
label.x = newX;
label.y = newY;
}
text: "Move me!"
}
}


f) Attached property
attached properties are kind of static member in C++ where attributes are accessed through class. Here it is accessed through object type rather than instantiated objects. attached properties can be accessed only in current level and not to its children.

it is declared as 
<AttachingType>.<propertyName>
<AttachingType>.on<SignalName>
<<MyListView.qml>>
import QtQuick 2.0
ListView {
© www.minhinc.com
p13
width: 240; height: 320
model: 3
delegate: Rectangle {
width: 100; height: 30
color: ListView.isCurrentItem ? "red" : "yellow"
}
}
© www.minhinc.com
p14
 
Day 1 Morning
  3. Building Blocks of QML
the QQuickItem is c++ class for Object type 'Item' in QtQuick. It provides most basic of all visual items. QQuickItem does not have any visual effect and it is item that is drawn on QQuickView.
For customised drawing
     QQuickItem
        / 
         -
         |
    -----------
    | MyItem  |
    -----------
    |QQuickItem::ItemHasContents|
    |QQuickItem::updatePainNode |
    -----------------------------

Use QPaintedItem for custom drawing.

      QQuickPaintedItem
         / 
          -
          |
       --------------
      | MyPaintedItem |
      ----------------
      | paint(QPainter*)|
      ------------------

import QtQuick 2.0

  Item {
      Image {
          source: "tile.png"
      }
      Image {
          x: 80
          width: 100
          height: 100
          source: "tile.png"
      }
      Image {
          x: 190
          width: 100
          height: 100
          fillMode: Image.Tile
          source: "tile.png"
      }
  }
Day 1 Morning
  3. Building Blocks of QML
The var type is a generic property type that can refer to any data type. It is equivalent to QVariant in C++ side.
It is equivalent to a regular JavaScript variable. For example, var properties can store numbers, strings, objects, arrays and functions:

Item {
  property var aNumber: 100
© www.minhinc.com
p15
  property var aBool: false
  property var aString: "Hello world!"
  property var anotherString: String("#FF008800")
  property var aColor: Qt.rgba(0.2, 0.3, 0.4, 0.5)
  property var aRect: Qt.rect(10, 10, 10, 10)
  property var aPoint: Qt.point(10, 10)
  property var aSize: Qt.size(10, 10)
  property var aVector3d: Qt.vector3d(100, 100, 100)
  property var anArray: [1, 2, 3, "four", "five", (function() { return "six"; })]
  property var anObject: { "foo": 10, "bar": 20 }
  property var aFunction: (function() { return "one"; })
  property var car: new Object({wheels: 4})
  property var car1: {'wheels':4}
  property var car2: ({wheels:4})
}
Day 1 Morning
  3. Building Blocks of QML
The QQmlListProperty class allows applications to expose list-like properties to QML.
QML has many list properties, where more than one object value can be assigned. The use of a list property from QML looks like this:

  FruitBasket {
      fruit: [
          Apple {},
          Orange{},
          Banana{}
      ]
  }

on c++ side it can be added to class like
 Q_PROPERTY(QQmlListProperty<Fruit> fruit READ fruit);
it can not read and write.
Day 1 Morning
  3. Building Blocks of QML
myapp
    |- mycomponents
        |- CheckBox.qml
        |- DialogBox.qml
        |- Slider.qml
    |- main
        |- application.qml

<application.qml>
<import "../mycomponents"

DialogBox {
    CheckBox {
        // ...
    }
    Slider {
        // ...
    }
}

import "../mycomponents" as MyComponents

MyComponents.DialogBox {
    // ...
}

for remotely located directory, directory must have a file 'qmldir'

© www.minhinc.com
p16
<qmldir>
CheckBox CheckBox.qml
DialogBox DialogBox.qml
Slider Slider.qml

directory can be imported like
import "http://www.my-example-server.com/myapp/mycomponents"

DialogBox {
    CheckBox {
        // ...
    }
    Slider {
        // ...
    }
}
© www.minhinc.com
p17
 
Day 1 Afternoon
  4. Composing UIs

One QQuickItem is nested in other QQuickItem. Its like parent child relationship.
import QtQuick 2.0
Rectangle {
 width: 400; height: 400
 color: "lightblue"
 Rectangle {
  x: 50; y: 50; width: 300; height: 300
  color: "green"
  Rectangle {
   x: 200; y: 150; width: 50; height: 50
   color: "white"
  }
 }
}

Day 1 Afternoon
  4. Composing UIs

Colors
import QtQuick 2.0
Item {
width: 300; height: 100
Rectangle {
x: 0; y: 0; width: 100; height: 100; color: "#ff0000"
}
Rectangle {
x: 100; y: 0; width: 100; height: 100
color: Qt.rgba(0,0.75,0,1)
}
Rectangle {
x: 200; y: 0; width: 100; height: 100; color: "blue"
}
}

Images
import QtQuick 2.0
Rectangle {
 width: 400; height: 400
 color: "black"
 Image {
  x: 150; y: 150
  source: "../images/rocket.png"
  scale:2.0
  rotation:45.0
 }
}

Gradients
import QtQuick 2.0
Rectangle {
 width: 400; height: 400
 gradient: Gradient {
  GradientStop {
   position: 0.0; color: "green"
  }
  GradientStop {
   position: 1.0; color: "blue"
  }
 }
}
Gradient Images
import QtQuick 2.0
Rectangle {
 width: 425; height: 200
 Image {
  x: 0; y: 0
  source: "../images/vertical-gradient.png"
 }
 Image {
  x: 225; y: 0
  source: "../images/diagonal-gradient.png"
 }
© www.minhinc.com
p18
}

Border Images
BorderImage {
 source: "content/colors.png"
 border { left: 30; top: 30; right: 30; bottom: 30; }
 horizontalMode: BorderImage.Stretch
 verticalMode: BorderImage.Repeat
 ...
}

Day 1 Afternoon
  4. Composing UIs

Text Elements
import QtQuick 2.0
Rectangle {
 width: 400; height: 400
 color: "lightblue"
 Text {
  x: 100; y: 100
  text: "Qt Quick"
  font.family: "Helvetica"
  font.pixelSize: 32
 }
}

Text Input
import QtQuick 2.0
Rectangle {
 width: 400; height: 400
 color: "lightblue"
 TextInput {
  x: 50; y: 100; width: 300
  text: "Editable text"
  font.family: "Helvetica"; font.pixelSize: 32
 }
}

Day 1 Afternoon
  4. Composing UIs

Anchor layout works only among parent and children.
import QtQuick 2.0
Rectangle {
width: 400; height: 200
color: "lightblue"
Image { id: book; source: "../images/book.svg"
anchors.left: parent.left
anchors.leftMargin: parent.width/16
anchors.verticalCenter: parent.verticalCenter }
Text { text: "Writing"; font.pixelSize: 32
anchors.left: book.right
anchors.leftMargin: 32
anchors.baseline: book.verticalCenter }
}
© www.minhinc.com
p19
 
Day 2 Morning
  5. User Input

When the user presses or releases a key, the following occurs:
1) Qt receives the key action and generates a key event.
2) If a QQuickWindow is the active window, the key event is delivered to it.
3) The key event is delivered by the scene to the Item with active focus. If no item has active focus, the key event is ignored.
4) If the QQuickItem with active focus accepts the key event, propagation stops. Otherwise the event is sent to the Item's parent until the event is accepted, or the root item is reached.

Rectangle has active focus and the A key is pressed, the event will not be propagated further. Upon pressing the B key, the event will propagate to the root item and thus be ignored.
Rectangle {
 width: 100; height: 100
 focus: true    <-----------------item with focus attribute
 Keys.onPressed: {
  if (event.key == Qt.Key_A) {
   console.log('Key A was pressed');
   event.accepted = true;
  }
 }
}

If the root Item is reached, the key event is ignored and regular Qt key handling continues.


Day 2 Morning
  5. User Input

 - Focus property
SubItem containing the 'focus' property true recieves the focus
Rectangle {
 color: "lightsteelblue"; width: 240; height: 25
 Text { id: myText }
 Item {
  id: keyHandler
  focus: true
  Keys.onPressed: {
   if (event.key == Qt.Key_A)
    myText.text = 'Key A was pressed'
   else if (event.key == Qt.Key_B)
    myText.text = 'Key B was pressed'
   else if (event.key == Qt.Key_C)
    myText.text = 'Key C was pressed'
  }
© www.minhinc.com
p20
 }
}

 - Focus Order
Focus Order is decided among items for which 'focus' attributes are set true. If Item is reused in other component then last item with focus attribute would receive the focus.

//Window code that imports MyWidget
Rectangle {
 id: window
 color: "white"; width: 240; height: 150
 Column {
  anchors.centerIn: parent; spacing: 15
  MyWidget {
   focus: true             //set this MyWidget to receive the focus
   color: "lightblue"
  }
  MyWidget {
   color: "palegreen"
  }
 }
}

The MyWidget code:
Rectangle {
 id: widget
 color: "lightsteelblue"; width: 175; height: 25; radius: 10; antialiasing: true
 Text { id: label; anchors.centerIn: parent}
 focus: true
 Keys.onPressed: {
  if (event.key == Qt.Key_A)
   label.text = 'Key A was pressed'
  else if (event.key == Qt.Key_B)
   label.text = 'Key B was pressed'
  else if (event.key == Qt.Key_C)
   label.text = 'Key C was pressed'
 }
}

 -Active focus
Which Item has the focus can be decided with property activeFocus.
Text {
 text: activeFocus ? "I have active focus!" : "I do not have active focus"
}

 -Focus Scope
Focusscope is a object type that can be used to make a particular item focused.

Day 2 Morning
  5. User Input
Any visual item can receive keyboard input through the Keys attached type.
© www.minhinc.com
p21
Day 2 Morning
  5. User Input
Day 2 Morning
  5. User Input
© www.minhinc.com
p22
 
Day 2 Morning
  6. Structures
a component is a resuable, encapsulated QML type with well-defined interfaces. Components are often defined by component files - that is, .qml files. the component type essentially allows QML componens to be defined inline, within a QML document, rather than as a separate QML file.

import QtQuick 2.0

Item {
    width: 100; height: 100

    Component {
        id: redSquare

        Rectangle {
            color: "red"
            width: 10
            height: 10
        }
    }

    Loader { sourceComponent: redSquare }
    Loader { sourceComponent: redSquare; x: 20 }
}

Day 2 Morning
  6. Structures
Day 2 Morning
  6. Structures
Day 2 Morning
  6. Structures
© www.minhinc.com
p23
 
Day 2 Morning
  12. Qt Quick Controls

Day 2 Morning
  12. Qt Quick Controls

Qt Quick Controls classes comes from module QtQuick.Controls
classes
-------
ApplicationWindow : Provides a top-level application window
BusyIndicator : A busy indicator
Button : A push button with a text label
Calendar : Provides a way to select dates from a calendar
CheckBox : A checkbox with a text label
ComboBox : Provides a drop-down list functionality
GroupBox : Group box frame with a title
Label : A text label
Menu : Provides a menu component for use as a context menu, popup menu, or as part of a menu bar
MenuBar : Provides a horizontal menu bar
ProgressBar : A progress indicator
RadioButton : A radio button with a text label
ScrollView : Provides a scrolling view within another Item
Slider : Provides a vertical or horizontal slider control
SpinBox : Provides a spin box control
SplitView : Lays out items with a draggable splitter between each item
StackView : Provides a stack-based navigation model
StackViewDelegate : A delegate used by StackView for loading transitions
StatusBar : Contains status information in your app
Switch : A switch Tab Represents the content of a tab in a TabView
TabView : A control that allows the user to select one of multiple stacked items
TableViewColumn : Used to define columns in a TableView or in a TreeView
TextArea : Displays multiple lines of editable formatted text
TextField : Displays a single line of editable plain text
ToolBar : Contains ToolButton and related controls
ToolButton : Provides a button type that is typically used within a ToolBar
TableView : Provides a list view with scroll bars, styling and header sections
TreeView : Provides a tree view with scroll bars, styling and header sections
Action : Abstract user interface action that can be bound to items
ExclusiveGroup : Way to declare several checkable controls as mutually exclusive
MenuItem : Item to add in a menu or a menu bar
MenuSeparator : Separator for items inside a menu
Stack : Provides attached properties for items pushed onto a StackView

Day 2 Morning
  12. Qt Quick Controls

ApplicationWindow is similar to QMainWindow on QWidget side which contains MeneBar ToolBar Statusbar like predefined gadgets.


example
ApplicationWindow {
 id: window
 visible: true
© www.minhinc.com
p24
 menuBar: MenuBar {
  Menu { MenuItem {...} }
  Menu { MenuItem {...} }
 }
 toolBar: ToolBar {
  RowLayout {
   anchors.fill: parent
   ToolButton {...}
  }
 }
 TabView {
  id: myContent
  anchors.fill: parent
  ...
 }
}

On C++ side QtQuickView can not be used as C++ type as it instantiate ApplicationWindow, instead QQmlApplicationEngine would be used. To fetch the QQuickWindow, root object can be returned

int main(int argc,char *argv[]){
QGuiApplication(argc, argv);
QQmlApplicationEngine engine("main.qml");
QQuickWindow *win=engine.rootObjects()[0];
return app.exec();
}

Day 2 Morning
  12. Qt Quick Controls

ListModel {
id: nameModel
ListElement { name: "Alice" }
ListElement { name: "Bob" }
ListElement { name: "Jane" }
ListElement { name: "Victor" }
ListElement { name: "Wendy" }
}
Component {
id: nameDelegate
Text {
text: name;
font.pixelSize: 32
}
}

Using Views
List Views
ListView {
anchors.fill: parent
model: nameModel
delegate: nameDelegate
clip: true
}

Day 2 Morning
  12. Qt Quick Controls

Grid Layout
import QtQuick 2.0
Grid {
x: 15; y: 15; width: 300; height: 300
columns: 2; rows: 2; spacing: 20
Rectangle { width: 125; height: 125; color: "red" }
Rectangle { width: 125; height: 125; color: "green" }
Rectangle { width: 125; height: 125; color: "silver" }
Rectangle { width: 125; height: 125; color: "blue" }
}

import QtQuick 2.0
© www.minhinc.com
p25
Rectangle {
width: 400; height: 400; color: "black"
Grid {
x: 5; y: 5
rows: 5; columns: 5; spacing: 10
Repeater { model: 24
Rectangle { width: 70; height: 70
color: "lightgreen" } }
}
}

Day 2 Morning
  12. Qt Quick Controls
© www.minhinc.com
p26
 
Day 2 Afternoon
  7. State and Transitions
A state is a set of batched changes from the default configuration. All "Item" QtQuick type have a default state (state=="") that defines the default configuration of objects and property values. New states can be defined by adding State items to the states property to allow items to switch between different configurations.

Various changes that can be achieved through state are
PropertyChanges
AnchorChanges
ParentChanges

Item QtQuick type has two properties
state:string
states:list<State>
Sample Code of states property of Item
import QtQuick 2.0
Rectangle {
 id: root               
    --------- state triggering in signal handler 
width: 100; height: 100
   /  
MouseArea {
  /   
id: mouseArea
  |   
anchors.fill: parent
  v   
onClicked: root.state == '' ? root.state = "red_color" : (root.state=='red_color' ? root.state = 'blue_color':root.state=""); } states: [ State { name: "red_color" PropertyChanges { target: root; color: "red" }
<---Changing targets property
}, State { name: "blue_color" PropertyChanges { target: root; color: "blue" }
<---Changing targets property
} ] }
Day 2 Afternoon
  7. State and Transitions
State QtQuick type has following property
changes : list<Change>
extend : string
name : string
when : bool
State would take effect only when 'when' property holds true
Rectangle {
 id: myRect
 width: 100; height: 100
 color: "red"
 MouseArea { id: mouseArea; anchors.fill: parent }
 states: State {
  name: "hidden"; when: mouseArea.pressed
  PropertyChanges { target: myRect; opacity: 0 }
© www.minhinc.com
p27
 }
}
Day 2 Afternoon
  7. State and Transitions
Transition comes into effect when Item changes its state. Item sits on default state in initial phase.
Transition has following property

animations : list<Animation>
enabled : bool
from : string
reversible : bool
running : bool
to : string

Here transition triggers NumberAnimation.
import QtQuick 2.0
Rectangle {
 id: rect
 width: 100; height: 100
 color: "red"
 MouseArea {
  id: mouseArea
  anchors.fill: parent
 }
 states: State {
  name: "moved"; when: mouseArea.pressed
  PropertyChanges { target: rect; x: 50; y: 50 }
 }
 transitions: Transition {
  NumberAnimation { properties: "x,y"; easing.type: Easing.InOutQuad }
 }
}
© www.minhinc.com
p28
© www.minhinc.com
p29
© www.minhinc.com
p30
© www.minhinc.com
p31
 
Day 3 Afternoon
  11. Animations
                       Animation
                          .
                         / \ 
                          -
                          |
+-----------+-----------+-+-----------+-------------+------------------+
|           |           | |           |             |                  |
----------- ----------- | ----------- ----------- ----------- ----------
|Anchor   | |Parallel | | |Parent   | |Path     | |Pause    | |Property|
|Animation| |Animation| | |Animation| |Animation| |Animation| |Action  |
----------- ----------- | ----------- ----------- ----------- ----------
                        |
                        |
      +-----------------+-----+
      |         |             |
----------- ---------  ------------
|Property | |Script |  |Sequential|
|Animation| |Action |  |Animation |
----------- ---------  ------------
    .
   / \ 
    -
    |
+-----------+-----------+
|           |           |
----------- ----------- ----------- -----------
|Color    | |Number   | |Rotation | |Vector3d |
|Animation| |Animation| |Animation| |Animation|
----------- ----------- ----------- -----------

Properties                  Signals               Methods
alwaysRunToEnd:bool    started()         complete()
loops:int              stopped()         pause()
paused:bool                              restart()
running:bool                             resume()
                                         start()
                                         stop()

Day 3 Afternoon
  11. Animations
Day 3 Afternoon
  11. Animations
© www.minhinc.com
p32
 
Day 3 Afternoon
  13. Presenting Data
Arranging Items
Positioners and repeaters make it easier to work with many items.
Positioner
An object of type Positioner is attached to the top-level child item within a Column, Row, Flow or Grid. It provides properties that allow a child item to determine where it exists within the layout of its parent Column, Row, Flow or Grid 

Attached Properties
index : int
isFirstItem : bool
isLastItem : bool

Repeater
The Repeater type is used to create a large number of similar items. Like other view types, a Repeater has a model and a delegate: for each entry in the model, the delegate is instantiated in a context seeded with data from the model. A Repeater item is usually enclosed in a positioner type such as Row or Column to visually position the multiple delegate items created by the Repeater.
Properties
 count : int
 delegate : Component
 model : any
Signals
 itemAdded(int index, Item item)
 itemRemoved(int index, Item item)
Methods
 Item itemAt(index)
Grid {  
<-- Positioner Type
Repeater { model: 16
<-------- Model
Rectangle {
<------- Delegate
id: rect width: 30; height: 30 border.width: 1 color: Positioner.isFirstItem ? "yellow" : "lightsteelblue" Text { text: rect.Positioner.index } } } }
Day 3 Afternoon
  13. Presenting Data
Data Models
Models and views provide a way to handle data sets
 - Models hold data or items
 - Views display data or items using delegates
© www.minhinc.com
p33
Data is provided to the delegate via named data roles which the delegate may bind to
Mainly of following kind of models.
 - ListModel
 - XmlListModel
 - VisualItemModel
 - ObjectModel
 - Integer as Model
 - Object Instances as Models
 - Repeaters

- ListModel
ListModel is a simple hierarchy of types specified in QML. The available roles are specified by the ListElement properties.
ListModel {
 id: fruitModel
 ListElement { name: "Apple";cost: 2.45 }
 ListElement { name: "Orange";cost: 3.25 }
 ListElement { name: "Banana";cost: 1.95 }
}
The above model has two roles, name and cost. These can be bound to by a ListView delegate, for example:
ListView {
 anchors.fill: parent
 model: fruitModel
 delegate: Row {
  Text { text: "Fruit: " + name }
  Text { text: "Cost: $" + cost }
 }
MouseArea {
 anchors.fill: parent
 onClicked: fruitModel.append({"cost": 5.95, "name":"Pizza"})
}
}
fruitModel can be appended through javascript code

- XmlListModel
XmlListModel allows construction of a model from an XML data source. The roles are specified via the XmlRole type. The type needs to be imported.
import QtQuick.XmlListModel 2.0
The following model has three roles, title, link and description:
XmlListModel {
 id: feedModel
 source: "http://rss.news.yahoo.com/rss/oceania"
 query: "/rss/channel/item"
 XmlRole { name: "title"; query: "title/string()" }
 XmlRole { name: "link"; query: "link/string()" }
 XmlRole { name: "description"; query: "description/string()" }
}

- ObjectModel
A ObjectModel contains the visual items to be used in a view. When a ObjectModel is used in a view, the view does not require a delegate since the ObjectModel already contains the visual delegate (items).
An item can determine its index within the model via the index attached property.
import QtQuick 2.0
import QtQml.Models 2.1
Rectangle {
 ObjectModel {
  id: itemModel
  Rectangle { height: 30; width: 80; color: "red" }
  Rectangle { height: 30; width: 80; color: "green" }
© www.minhinc.com
p34
  Rectangle { height: 30; width: 80; color: "blue" }
 }
 ListView {
  anchors.fill: parent
  model: itemModel
 }
}

-Integer as Model
An integer can be used as a model that contains a certain number of types. In this case, the model does not have any data roles.
The following example creates a ListView with five elements:
Item {
 width: 200; height: 250
 Component {
  id: itemDelegate
  Text { text: "I am item number: " + index }
 }
 ListView {
  anchors.fill: parent
  model: 5
  delegate: itemDelegate
 }
}
 
- Object Instances as Models
An object instance can be used to specify a model with a single object type. The properties of the object are provided as roles.
Rectangle {
 width: 200; height: 250
 Text {
  id: myText
  text: "Hello"
  color: "#dd44ee"
 }
 Component {
  id: myDelegate
  Text { text: model.color }  
<--- Explicitly calling model.color 
} ListView { anchors.fill: parent anchors.topMargin: 30 model: myText delegate: myDelegate } }

-Repeaters
Repeaters create items from a template for use with positioners, using data from a model. Combining repeaters and positioners is an easy way to lay out lots of items. A Repeater item is placed inside a positioner, and generates items that the enclosing positioner arranges. Each Repeater creates a number of items by combining each element of data from a model, specified using the model property.
import QtQuick 2.0
Rectangle {
 width: 400; height: 400; color: "black"
 Grid {
  x: 5; y: 5
  rows: 5; columns: 5; spacing: 10
  Repeater { model: 24
   Rectangle { width: 70; height: 70
    color: "lightgreen"
    Text { text: index
     font.pointSize: 30
     anchors.centerIn: parent } }
  }
 }
}
- Using Views
Views are containers for collections of items. They are feature-rich and can be customizable to meet style or behavior requirements.
Views allow visual customization through decoration properties such as the header, footer, and section properties. By binding an object, usually another visual object, to these properties, the views are decoratable. A footer may include a Rectangle type showcasing borders or a header that displays a logo on top of the list.
© www.minhinc.com
p35
A set of standard views are provided in the basic set of Qt Quick graphical types:
ListView - arranges items in a horizontal or vertical list
GridView - arranges items in a grid within the available space
PathView - arranges items on a path

- ListView
ListModel {
 id: nameModel
 ListElement { name: "Alice" }
 ListElement { name: "Bob" }
 ListElement { name: "Jane" }
 ListElement { name: "Harry" }
 ListElement { name: "Wendy" }
}
Component {
 id: nameDelegate
 Text {
  text: name;
  font.pixelSize: 24
 }
}
ListView {
 anchors.fill: parent
 clip: true
 model: nameModel
 delegate: nameDelegate
 header: bannercomponent
 footer: Rectangle {
  width: parent.width; height: 30;
  gradient: clubcolors
 }
 highlight: Rectangle {
  width: parent.width
  color: "lightgray"
 }
}
Component {     //instantiated when header is processed
 id: bannercomponent
 Rectangle {
  id: banner
  width: parent.width; height: 50
  gradient: clubcolors
  border {color: "#9EDDF2"; width: 2}
  Text {
   anchors.centerIn: parent
   text: "Club Members"
   font.pixelSize: 32
  }
 }
}
Gradient {
 id: clubcolors
 GradientStop { position: 0.0; color: "#8EE2FE"}
 GradientStop { position: 0.66; color: "#7ED2EE"}
}

- Using Delegates 
Views need a delegate to visually represent an item in a list. A view will visualize each item list according to the template defined by the delegate. Items in a model are accessible through the index property as well as the item's properties.
Component {
id: petdelegate
Text {
 id: label
 font.pixelSize: 24
 text: if (index == 0)
  label.text = type + " (default)"
 else
  text: type
 }
}

© www.minhinc.com
p36
The list view to which the delegate is bound is accessible from the delegate through the ListView.view property. Likewise, the GridView GridView.view is available to delegates. The corresponding model and its properties, therefore, are available through ListView.view.model. In addition, any defined signals or methods in the model are also accessible.

Rectangle {
 width: 200; height: 200
ListModel {
 id: fruitModel
 property string language: "en"
 ListElement {
  name: "Apple"
  cost: 2.45
 }
 ListElement {
  name: "Orange"
  cost: 3.25
 }
 ListElement {
  name: "Banana"
  cost: 1.95
 }
}
Component {
 id: fruitDelegate
 Row {
  id: fruit
  Text { text: " Fruit: " + name; color: fruit.ListView.view.fruit_color }
  Text { text: " Cost: $" + cost }
  Text { text: " Language: " + fruit.ListView.view.model.language }
 }
}
ListView {
 property color fruit_color: "green"
 model: fruitModel
 delegate: fruitDelegate
 anchors.fill: parent
}
}

Day 3 Afternoon
  13. Presenting Data
© www.minhinc.com
p37