QML CPP Integration
QML CPP Integration
Training Course
Visit us at http://qt.digia.com
Produced by Digia Plc.
Material based on Qt 5.0, created on September 27, 2012
Digia Plc.
2/74
Objectives
The QML runtime environment
understanding of the basic architecture ability to set up QML in a C++ application
3/74
Declarative Environment
4/74
Overview
Qt Quick is a combination of technologies:
A set of components, some graphical A declarative language: QML
based on JavaScript running on a virtual machine
Declarative Environment
5/74
Declarative Environment
6/74
Setting up QtQuick
QT SOURCES += quick = main.cpp RESOURCES = simpleviewer.qrc
Declarative Environment
7/74
8/74
The notify signal is needed for correct property bindings! Q_PROPERTY must be at top of class
9/74
10/74
11/74
What is exported?
Accessible from QML:
Properties Signals Slots Methods marked with Q_INVOKABLE Enums registered with Q_ENUMS
class Circle { Q_ENUMS(Style) public: enum Style { Outline, Filled }; ... };
12/74
13/74
Overview
Steps to dene a new type in QML:
In C++: Subclass either QObject or QQuickItem In C++: Register the type with the QML environment In QML: Import the module containing the new item In QML: Use the item like any other standard item Non-visual types are QObject subclasses Visual types (items) are QQuickItem subclasses
QQuickItem is the C++ equivalent of Item
14/74
15/74
16/74
17/74
18/74
This registers the Timer C++ class Available from the CustomComponents QML module
version 1.0 (rst number is major; second is minor)
19/74
20/74
Adding Properties
In the main.qml le:
Rectangle { ... Timer { id: timer interval: 3000 } }
21/74
Declaring a Property
In the timer.h le:
class Timer : public QObject { Q_OBJECT Q_PROPERTY( int interval READ interval WRITE setInterval NOTIFY intervalChanged ) ...
22/74
Declare the getter and setter Declare the notier signal Contained QTimer object holds actual value
23/74
Do not emit notier signal if value does not actually change Important to break cyclic dependencies in property bindings
24/74
25/74
Adding Signals
In the main.qml le:
Rectangle { ... Timer { interval: 3000 onTimeout: { console.log( "Timer fired!" ); } } }
26/74
Declaring a Signal
In the timer.h le:
... signals: void timeout(); void intervalChanged(); ...
27/74
28/74
In C++:
the QTimer::timeout() signal is emitted connection means Timer::timeout() is emitted
In QML:
the Timer item's onTimeout handler is called outputs message to stderr
29/74
2 .
30/74
Adding Slots
In the main.qml le:
Rectangle { Timer { id: timer onTimeout: { console.log( "Timer fired!" ); } } MouseArea { onClicked: { if ( timer.active == false ) { timer.start(); } else { timer.stop(); } } } }
31/74
Adding Slots
Timer now has start() and stop() methods Normally, could just use properties to change state... For example a running property
Demo qml-cpp-integration/ex_timer_slots .
32/74
Declaring Slots
In the timer.h le:
... public slots: void start(); void stop(); ...
Added start() and stop() slots to public slots section No difference to declaring slots in pure C++ application
33/74
Implementing Slots
In the timer.cpp le:
void Timer::start() { if ( m_timer->isActive() ) return; m_timer->start(); emit activeChanged(); } void Timer::stop() { if ( !m_timer->isActive() ) return; m_timer->stop(); emit activeChanged(); }
34/74
Adding Methods
In the main.qml le:
Rectangle { Timer { id: timer interval: timer.randomInterval( 500, 1500 ) onTimeout: { console.log( "Timer fired!" ); } } }
35/74
Declaring a Method
In the timer.h le:
... public: explicit Timer( QObject* parent = 0 ); ... Q_INVOKABLE int randomInterval( int min, int max ) const; ...
36/74
Implementing a Method
In the timer.cpp le:
int Timer::randomInterval( int min, int max ) const { int range = max - min; int msec = min + qrand() % range; qDebug() << "Random interval =" << msec << "msecs"; return msec; }
37/74
38/74
39/74
40/74
41/74
42/74
43/74
44/74
45/74
46/74
47/74
48/74
49/74
50/74
Using Enums
class IntervalSettings :public QObject { Q_OBJECT Q_ENUMS( Unit ) Q_PROPERTY( Unit unit READ unit ...) public: enum Unit { Minutes, Seconds, MilliSeconds }; ... }
51/74
52/74
53/74
54/74
Demo qml-cpp-integration/ex_timer_custom_types .
55/74
A Chart item
with a bars list property accepting custom Bar items
Demo qml-cpp-integration/ex-custom-collection-types .
56/74
57/74
Dene the getter function and notication signal Dene an append function for the list property
58/74
59/74
60/74
using a custom item that has been declared and registered declare properties with QQmlListProperty implement a getter and an append function for each property read-only properties, but read-write containers read-only containers dene append functions that simply return
61/74
Default Property
One property can be marked as the default
class ChartItem : public QQuickPaintedItem { Q_OBJECT Q_PROPERTY(QQmlListProperty<BarItem> bars READ bars NOTIFY barsChanged) Q_CLASSINFO("DefaultProperty", "bars") ...
62/74
Plug-ins
63/74
using source and header les for a working custom type developed separately then deployed with an application write QML-only components then rewrite in C++ use placeholders for C++ components until they are ready
Plug-ins
64/74
Plug-ins
65/74
Plug-ins
66/74
Ensure that the project is built as a Qt plugin QtQuick module is added to the Qt conguration Plugin is written to a plugins directory
Plug-ins
67/74
plugin followed by
the plugin name: ellipseplugin the plugin path relative to the qmldir le: ../plugins
Plug-ins
68/74
Use the custom item directly No need to import any custom modules
qmldir and ellipse9s.qml are in the same project directory Ellipse is automatically imported into the global namespace
Plug-ins
69/74
Plug-ins
70/74
The Ellipse item is part of the Shapes module A different URI makes a different import necessary; e.g.,
plugin->registerTypes("com.nokia.qt.examples.Shapes");
corresponds to
import com.nokia.qt.examples.Shapes 9.0
Plug-ins
71/74
Plug-ins
72/74
implemented in C++
The GUI is implemented in QML Missing: Is the glue which makes the two parts work together. STEPS are available in the le readme.txt.
Lab qml-cpp-integration/lab-tcp-connection .
Plug-ins
73/74
Digia Plc. Digia, Qt and the Digia and Qt logos are the registered trademarks of Digia Plc. in Finland and other countries worldwide.
Plug-ins
74/74