best practices in qt quick/qml - part i
TRANSCRIPT
![Page 1: Best Practices in Qt Quick/QML - Part I](https://reader036.vdocuments.us/reader036/viewer/2022081418/55b6e7f5bb61eb69688b47fa/html5/thumbnails/1.jpg)
Qt Quick Best PracticesPart I
Justin Noel Senior Consulting EngineerICS, Inc.
![Page 2: Best Practices in Qt Quick/QML - Part I](https://reader036.vdocuments.us/reader036/viewer/2022081418/55b6e7f5bb61eb69688b47fa/html5/thumbnails/2.jpg)
Agenda
• Building Blocks of QML• Qt Properties• Declarative Code• Anchors
![Page 3: Best Practices in Qt Quick/QML - Part I](https://reader036.vdocuments.us/reader036/viewer/2022081418/55b6e7f5bb61eb69688b47fa/html5/thumbnails/3.jpg)
Building Blocks of QML
![Page 4: Best Practices in Qt Quick/QML - Part I](https://reader036.vdocuments.us/reader036/viewer/2022081418/55b6e7f5bb61eb69688b47fa/html5/thumbnails/4.jpg)
QObject
• Heart and Soul of Qt Object• Signals and Slots are implemented here• QObjects can have “child objects”
• Parents have some control over children• Deleting them, laying them out, etc
• Also Qt Properties!
![Page 5: Best Practices in Qt Quick/QML - Part I](https://reader036.vdocuments.us/reader036/viewer/2022081418/55b6e7f5bb61eb69688b47fa/html5/thumbnails/5.jpg)
Introspection
• QObjects can report at runtime• Class name, Super class• Lists of signals and list their arguments• Lists of functions and list their arguments• Invoke methods by name
• QMetaObject::invokeMethod(objPtr, “function”…)
![Page 6: Best Practices in Qt Quick/QML - Part I](https://reader036.vdocuments.us/reader036/viewer/2022081418/55b6e7f5bb61eb69688b47fa/html5/thumbnails/6.jpg)
Meta Object Compiler
• Introspection info is generated by moc• Reads header files. Writes source code
• moc -o moc_class.cpp class.h
• MetaObject is static • One instance per QObject subclass
![Page 7: Best Practices in Qt Quick/QML - Part I](https://reader036.vdocuments.us/reader036/viewer/2022081418/55b6e7f5bb61eb69688b47fa/html5/thumbnails/7.jpg)
QQuickItem
• Most Qt Objects inherit QObject• QQuickItem is no exception
• Gets many of it’s features directly from QObject
• We will be leveraging these capabilities throughout class
![Page 8: Best Practices in Qt Quick/QML - Part I](https://reader036.vdocuments.us/reader036/viewer/2022081418/55b6e7f5bb61eb69688b47fa/html5/thumbnails/8.jpg)
Deferred Deletion
• Qt is an event driven GUI toolkit• Deleting object can be tricky in an event based
system• Deleting objects from within an event• Deleting the sender object from a signal and slot
connection
• QObject has a deleteLater() method
![Page 9: Best Practices in Qt Quick/QML - Part I](https://reader036.vdocuments.us/reader036/viewer/2022081418/55b6e7f5bb61eb69688b47fa/html5/thumbnails/9.jpg)
deleteLater()
• Posts an event to the event loop• On the next lap of the loop
• The object is deleted and all events cleared
• destroy() in QML is QObject::deleteLater()
![Page 10: Best Practices in Qt Quick/QML - Part I](https://reader036.vdocuments.us/reader036/viewer/2022081418/55b6e7f5bb61eb69688b47fa/html5/thumbnails/10.jpg)
QVariant
• Qt’s “Anything” class• Think: Typed void*• Supports most Qt data types out of the box
• Easy to add support for your own types• Automatically supports all pointer types
![Page 11: Best Practices in Qt Quick/QML - Part I](https://reader036.vdocuments.us/reader036/viewer/2022081418/55b6e7f5bb61eb69688b47fa/html5/thumbnails/11.jpg)
QVariant and QML
• QVariant maps to var in JavaScript• Used to pass data back and forth to C++• If you register your types correctly you can
attain runtime type safety
![Page 12: Best Practices in Qt Quick/QML - Part I](https://reader036.vdocuments.us/reader036/viewer/2022081418/55b6e7f5bb61eb69688b47fa/html5/thumbnails/12.jpg)
QVariant Containers
• QVariantList maps to Array in JavaScript• QList<QVariantMap> can be used with JSON
syntax JavaScript• Better off using QJson classes
• If you are using JSON data• Easier to convert back to JSON
![Page 13: Best Practices in Qt Quick/QML - Part I](https://reader036.vdocuments.us/reader036/viewer/2022081418/55b6e7f5bb61eb69688b47fa/html5/thumbnails/13.jpg)
Qt Properties
![Page 14: Best Practices in Qt Quick/QML - Part I](https://reader036.vdocuments.us/reader036/viewer/2022081418/55b6e7f5bb61eb69688b47fa/html5/thumbnails/14.jpg)
Qt Properties
• Combination of Get/Set/Notify• Allows introspection system to use these
functions as one concept• Properties have been in Qt for a very long time
• Qt Designer is based on properties• QML is also based on properties
![Page 15: Best Practices in Qt Quick/QML - Part I](https://reader036.vdocuments.us/reader036/viewer/2022081418/55b6e7f5bb61eb69688b47fa/html5/thumbnails/15.jpg)
Declaration of a Qt Property#include <QObject>
class Car : public QObject{ Q_OBJECT Q_PROPERTY(int value READ value WRITE setValue NOTIFY valueChanged)
public: int getValue() const; void setValue(int newValue);
signals: void valueChanged(int value);};
![Page 16: Best Practices in Qt Quick/QML - Part I](https://reader036.vdocuments.us/reader036/viewer/2022081418/55b6e7f5bb61eb69688b47fa/html5/thumbnails/16.jpg)
Qt Property with Enum#include <QObject>
class Car : public QObject{ Q_OBJECT Q_ENUMS(KeyState) Q_PROPERTY(KeyState keyState READ keyState NOTIFY keyStateChanged)public: enum KeyState { KeyOff, KeyOn, KeyStart }; [...]};
![Page 17: Best Practices in Qt Quick/QML - Part I](https://reader036.vdocuments.us/reader036/viewer/2022081418/55b6e7f5bb61eb69688b47fa/html5/thumbnails/17.jpg)
Getting and Setting Qt Properties
void someFunction(Qobject* obj){ // Getting QVariant propValue = obj->property(“value”); qDebug() << propValue.typeName() << propValue.toInt();
//Setting QVariant newValue = QVariant::fromValue(Car::KeyOn); obj->setProperty(“keyState”, newValue);}
![Page 18: Best Practices in Qt Quick/QML - Part I](https://reader036.vdocuments.us/reader036/viewer/2022081418/55b6e7f5bb61eb69688b47fa/html5/thumbnails/18.jpg)
Dynamic Propeties
• Properties are Key-Value Pairs• QObject can create properties on demand
• Less type safe, but perfectly useful for QML
obj->setProperty(“newPropName”, 1);obj->setProperty(“another”, “Value”);
int propInt = obj->property(“newPropName”).toInt();QString propString = obj->property(“another”).toString();
![Page 19: Best Practices in Qt Quick/QML - Part I](https://reader036.vdocuments.us/reader036/viewer/2022081418/55b6e7f5bb61eb69688b47fa/html5/thumbnails/19.jpg)
Declarative Code
![Page 20: Best Practices in Qt Quick/QML - Part I](https://reader036.vdocuments.us/reader036/viewer/2022081418/55b6e7f5bb61eb69688b47fa/html5/thumbnails/20.jpg)
Basic QML Syntax
• QML is declarative language• With hooks for procedural JavaScript
• Use as little JavaScript as possible
• QML files a read at runtime• The declarative parts create C++ instances• JavaScript is JIT interpreted
![Page 21: Best Practices in Qt Quick/QML - Part I](https://reader036.vdocuments.us/reader036/viewer/2022081418/55b6e7f5bb61eb69688b47fa/html5/thumbnails/21.jpg)
QtQuick Hello Worldimport QtQuick 2.2
Rectangle{ id: toplevel color: “blue” Text { text: “Hello World” }
MouseArea { anchors.fill: parent onClicked: Qt.quit() }}
![Page 22: Best Practices in Qt Quick/QML - Part I](https://reader036.vdocuments.us/reader036/viewer/2022081418/55b6e7f5bb61eb69688b47fa/html5/thumbnails/22.jpg)
Qt Quick Items
• Rectangle, Text and MouseArea• Are implemented in C++• Instances of QQuickRectangle, QQuickText, Etc• Loading QML is slower than compiled code
• At runtime performance is great
![Page 23: Best Practices in Qt Quick/QML - Part I](https://reader036.vdocuments.us/reader036/viewer/2022081418/55b6e7f5bb61eb69688b47fa/html5/thumbnails/23.jpg)
QML Bindings
• “:” is the binding operator• Right of the binding operator is JavaScript• Text {
text: “Hello World ” + Math.rand() }
• If the expression is simple• The full JavaScript interpreter may be skipped
• More on this later in the webinar series
![Page 24: Best Practices in Qt Quick/QML - Part I](https://reader036.vdocuments.us/reader036/viewer/2022081418/55b6e7f5bb61eb69688b47fa/html5/thumbnails/24.jpg)
Bindings are Declarative
• When any property used in a binding changes the expression is recalculated
Gauge { value: Math.min(gaugeMax, Math.max(gaugeMin, oilPressure.value)) }
• Value is updated whenever properties change• gaugeMax, gaugeMin or oilPressure.value
![Page 25: Best Practices in Qt Quick/QML - Part I](https://reader036.vdocuments.us/reader036/viewer/2022081418/55b6e7f5bb61eb69688b47fa/html5/thumbnails/25.jpg)
JavaScript is Procedural
• Avoid this!Gauge {
Component.onCompleted: { setGaugeValue(oilPressure.value) oilPressure.valueChanged.connect(setGaugeValue) }
onGaugeMinChanged: setGaugeValue(value) onGaugeMaxChanged: setGaugeValue(value)
function setGaugeValue(oilValue) { value = Math.min(gaugeMax, Math.max(gaugeMin, oilValue)) }}
![Page 26: Best Practices in Qt Quick/QML - Part I](https://reader036.vdocuments.us/reader036/viewer/2022081418/55b6e7f5bb61eb69688b47fa/html5/thumbnails/26.jpg)
Broken Bindings
• Assignment operator breaks bindings• Binding works for awhile. Then doesn’t.• Solution: Use States
• More in later in the webinar series Gauge { id: gauge visible: Dashboard.isOilPressureVisible }
Button { onClicked: { // Tries to temporarily hide gauge if(gauge.visible) gauge.visible = false
else gauge.visible = Dashboard.isOilPressureVisible } }
![Page 27: Best Practices in Qt Quick/QML - Part I](https://reader036.vdocuments.us/reader036/viewer/2022081418/55b6e7f5bb61eb69688b47fa/html5/thumbnails/27.jpg)
Anchors
![Page 28: Best Practices in Qt Quick/QML - Part I](https://reader036.vdocuments.us/reader036/viewer/2022081418/55b6e7f5bb61eb69688b47fa/html5/thumbnails/28.jpg)
Dead Reckoning LayoutItem { width: 800; height: 400; Rectangle { id:rectA color: 'red‘ height: 50 ; width: 70 x: 0; y: 0 }
Rectangle { id:rectB color: 'blue‘ height: rectA.height * 2; width: rectA.width * 2 x: 0; y: 100 }}
![Page 29: Best Practices in Qt Quick/QML - Part I](https://reader036.vdocuments.us/reader036/viewer/2022081418/55b6e7f5bb61eb69688b47fa/html5/thumbnails/29.jpg)
Why is dead reckoning bad?
• The good:• It resizes correctly• It uses bindings so it’s “declarative”
• The bad:• There are a lot of binding re-calculations
• Each recalculation is run in JavaScript
• Cascading bindings cause intermediate states
![Page 30: Best Practices in Qt Quick/QML - Part I](https://reader036.vdocuments.us/reader036/viewer/2022081418/55b6e7f5bb61eb69688b47fa/html5/thumbnails/30.jpg)
Binding Recalculation
• This example has ~40 items• If each item needs 2 bindings
• 80 Recalculations on resize• Not including intermediate states
![Page 31: Best Practices in Qt Quick/QML - Part I](https://reader036.vdocuments.us/reader036/viewer/2022081418/55b6e7f5bb61eb69688b47fa/html5/thumbnails/31.jpg)
Intermediate StatesExample 2.2. src/anchors/tst_bindings_1.qmlItem { property int c: a + b property int a property int b: a
onAChanged: console.log("a == " + a) onBChanged: console.log("b == " + b) onCChanged: console.log("c == " + c) Component.onCompleted: a = 1}
Output: a == 1 c == 1 b == 1 c == 2
![Page 32: Best Practices in Qt Quick/QML - Part I](https://reader036.vdocuments.us/reader036/viewer/2022081418/55b6e7f5bb61eb69688b47fa/html5/thumbnails/32.jpg)
Anchors Are Better!
• Anchors are stored and calculated in C++• Remember all Items are actually C++ instances• Anchors let you attach an item to other items
• Parent item• Any sibling item
• Anyone remember the Motif Form Widget?• Eerily similar. What’s old is new again!
![Page 33: Best Practices in Qt Quick/QML - Part I](https://reader036.vdocuments.us/reader036/viewer/2022081418/55b6e7f5bb61eb69688b47fa/html5/thumbnails/33.jpg)
Anchor Lines
• There are 6 anchors lines all Items have
• Text item has a 7th anchor called baseline• Bottom of text without descenders
![Page 34: Best Practices in Qt Quick/QML - Part I](https://reader036.vdocuments.us/reader036/viewer/2022081418/55b6e7f5bb61eb69688b47fa/html5/thumbnails/34.jpg)
Setting AnchorsRectangle { width: 800; height:600
Rectangle { id: rect1 width: 400 anchors.top: parent.top anchors.bottom: parent.bottom }
Rectangle { id: rect2 anchors { top: parent.top; bottom: parent.bottom left: rect1.right; right: parent.right } }}
![Page 35: Best Practices in Qt Quick/QML - Part I](https://reader036.vdocuments.us/reader036/viewer/2022081418/55b6e7f5bb61eb69688b47fa/html5/thumbnails/35.jpg)
Anchor Margins
• Each item has 6 adjustable margins
• Not shown are [horizontal|vertical]CenterOffset• Text has a baselineOffset margin• anchors.margins sets all outer margins at once
![Page 36: Best Practices in Qt Quick/QML - Part I](https://reader036.vdocuments.us/reader036/viewer/2022081418/55b6e7f5bb61eb69688b47fa/html5/thumbnails/36.jpg)
Complex Anchors
• Set multiple anchors at once• anchors.fill: anotherItem
• Sets left, right, top and bottom• Can use all outer margins
• anchors.centerIn: anotherItem• Sets horizontalCenter and verticalCenter• Can use horizontal and vertical offsets
![Page 37: Best Practices in Qt Quick/QML - Part I](https://reader036.vdocuments.us/reader036/viewer/2022081418/55b6e7f5bb61eb69688b47fa/html5/thumbnails/37.jpg)
Upcoming Webinars• Qt Quick Best Practices
• Part 2 July 9th 1:00 PM EST• Creating New Items
• States and Transitions
• Part 3 July 23 1:00 PM EST• C++ Integration
• Creating QML Modules
• Part 4 August 6th 1:00 PM EST• Dynamic Item Creation
• Keyboard Input Handling
• Performance Tips
Register Now: ics.com/webinars
![Page 38: Best Practices in Qt Quick/QML - Part I](https://reader036.vdocuments.us/reader036/viewer/2022081418/55b6e7f5bb61eb69688b47fa/html5/thumbnails/38.jpg)
Thank You!
Justin NoelSenior Consulting Engineer
ICS, Inc.