0% found this document useful (0 votes)
24 views83 pages

Qt-QML Best of Best ICS Webinars

Integrated Computer Solutions (ICS) offers Qt training, consulting, and software development, and is a major sponsor of Qt conferences. The document outlines best practices in Qt Quick/QML through a series of webinars, detailing various topics such as QObjects, QVariants, and QML bindings. Presenters include Justin Noel and Langsten Ball, with additional resources available through provided links to slides and training materials.

Uploaded by

Vũ Ngọc Hùng
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PPTX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
24 views83 pages

Qt-QML Best of Best ICS Webinars

Integrated Computer Solutions (ICS) offers Qt training, consulting, and software development, and is a major sponsor of Qt conferences. The document outlines best practices in Qt Quick/QML through a series of webinars, detailing various topics such as QObjects, QVariants, and QML bindings. Presenters include Justin Noel and Langsten Ball, with additional resources available through provided links to slides and training materials.

Uploaded by

Vũ Ngọc Hùng
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PPTX, PDF, TXT or read online on Scribd
You are on page 1/ 83

The Best of the ICS

Best Practices
Webinars
OC QT/QML MEETUP
Who is Integrated
Computer Solutions?
◦ Provides Qt Training, Consulting and Software
Development
◦ Major sponsor of Qt Conferences
◦ https://www.ics.com/qt
Online Training
https://www.ics.com/learning/webinars
Specifically:
Best Practices in Qt Quick/QML - Part I
Best Practices in Qt Quick/QML - Part II
Best Practices in Qt Quick/QML - Part III
Best Practices in Qt Quick/QML - Part IV
Presenters
Justin Noel, Senior Consulting Engineer, ICS, Inc.
Langsten Ball, ICS Consulting Engineer, ICS, Inc.
Slides for ICS Webinars
https://www.slideshare.net/ICSinc/best-practices-i
n-qt-quick-qml-part-1
https://www.slideshare.net/ICSinc/best-practices-i
n-qt-quick-qml-part-ii
https://www.slideshare.net/ICSinc/best-practices-i
n-qt-quickqml-part-iii
https://www.slideshare.net/ICSinc/best-practices-i
n-qt-quickqml-part-iv
QObjects Part I, slides 4,5
5:50 “QObjects can have children”
Create a QObject with another QObject and
the object will add itself to its parent’s
children.
6:16 QObjects provide the introspection
information that is fundamental to Qt & QML.
See http://doc.qt.io/qt-5/qobject.html
QObjects slides 5-9
00:07:10 Any object that you can get a pointer to,
you can get a QMetaObject to get lists of
functions, members, signals, and call functions
by name:
QObject::metaObject() const
00:10:10 All QML objects are created from
QQuickItem C++ objects.
00:11:20 Call QObject::deleteLater() if you need to
delete a QObject; it will be deleted in the next
lap of the event loop instead of immediately.
QVariants slides 10-12
00:12:30 QVariant's are Qt's "Anything" class.
00:13:40 QVariant's map to var in JavaScript.
00:14:10 Discussion on QVariant containers…

How to make a type “QVariant


compatible”

For a type to be QVariant compatible its


members must be QVariant compatible.
Qt Properties slides 14-17
00:15:50 Example of a declaration of a Qt Property
00:17:00 Qt Property with enum
00:17:20 Use Q_ENUM to expose an enum to QML.
Note: Video says Q_ENUMS macro, which
is deprecated.
00:18:00 Example of accessing properties from C++
00:19:00 Possible to create properties dynamically.
Don't blink or you'll miss this tip.
QML slide 20
00:20:15 Strive to write as little JavaScript as
possible.
00:20:45 Explanation of loading QML at run time.
Instancing, then binding.
00:21:50 Most of a QML document gets processed
when the document is loaded but the
chunks of JavaScript get interpreted over
time.
QML slides 20-22
00:22:40 Important to understand which parts of
QML generate C++ objects, and which
generate JavaScript.
00:23:30 If JavaScript snippets are simple, a very
optimized interpreter is invoked.
00:24:40 A giant application of widgets loads faster
than a giant QML application.
00:25:15 Runtime performance of QML is very
good.
QML Bindings slide 23, 24
00:25:45 The colon is a binding operator, not an
assignment operator. If you use a variable
in a binding, the binding is smart enough
that the binding will be recalculated if any
variable in the binding changes.
00:26:40 Bindings make your QML code
declarative. This discussion gives a good
example of when declarative rules
compared to procedural programming.
QML Bindings slide 25, 26
00:28:15 Avoid using the procedural version of
declarative code.
00:29:50 Use declarative code, not procedural
code and let the QML optimizer do it's
thing.
00:30:30 Example of breaking bindings.
Similar to order-of-execution defects in
difficulty of finding/fixing.
00:32:30 Use states to change bindings.
Anchors slide 28-31
00:33:10 Example of layout using dead reckoning
instead of anchors.
00:34:10 Dead reckoning is bad because it causes
cascading binding evaluation.
00:34:45 Cascading binding create intermediate states.
00:35:40 Intermediate states are caused when
bindings depend on multiple values. Example
shows a simple size change resulting in
multiple passes to evaluate a single binding.
Anchors slide 32-36
00:36:30 Anchors were designed to address poor layout
performance.
00:37:30 The 6 (or 7 for Text) anchors demonstrated.
00:38:20 If you are using “if” statements in an anchor you
should be using states.
00:38:50 An anchor margin is only applied if you set the
corresponding anchor.
00:39:20 Set multiple anchors at once: fill or centerIn let
you use the individual margins or the center offset
anchors, respectively.
Part I Q&A
00:42:55 Using Qt on Windows with the Angle
project is using OpenGL ES 2.0
00:43:35 Excellent discussion of why to separate
code into C++ and QML.
When given an application that is a hybrid
of C++ and QML, create model and
business logic in C++ to make your objects
testable.
Part I Q&A
00:45:05 Difference between a Window and a Rectangle; a
Window is a Windowing operation system object
with access to OS window properties like title and
icon. A Rectangle can be used on platforms that do
not have a windowing system.
00:47:10 Advantages of QML? QML is very good at
animated user interfaces. Those animations are
often not available to Widgets. It is great for
touchscreen applications.
00:48:20 Using QML usually forces you to have a strong
separation between front end and back end.
Part I Q&A
00:49:30 Qt Creator launches QML JS Debugger
which is used over TCP when debugging
QML.
00:51:05 Hard to step debugging from QML to C++.
Best to set a breakpoint in QML and
another in C++ that the QML will call.
Properties Part II, slide 4-6
00:02:50 Any instance of an Item is basically a
subclass and you are extending the Item.
00:04:30 Properties can be QML types. These are
pointers to the elements that are created
behind the scenes.
00:04:50 Using explicit types are faster than var
types (QVariant is the backing type)
Property TypesPart II, slides
7-9
00:06:05 Example of a list property (property
list<point> points).
00:07:30 Create a new QML element by creating a
new QML file.
00:07:55 Use a name that implies purpose when
naming a QML file.
Button ExamplePart II,
slides 10-12
00:08:40 Example of an inline button.
00:10:00 What the button code looks like when
componentized.
00:10:30 Example of the new button code.
Button ExamplePart II,
slides 12
00:11:00 Example of the property alias text.
00:11:35 Use an alias instead of a string to avoid
allocating extra memory.
00:12:25 Use signal forwarding to control the
interface of internal elements that you
want to expose. In this case, the
MouseArea clicked() signal.
Button ExamplePart II,
slides 11-13
00:13:35 Shows binding to the signal.
00:14:13 Aliases allow hiding implementation
details.
00:14:30 Using an alias avoids having a small
JavaScript snippet evaluating a binding.
Property ScopePart II, slides
15-16
00:15:00 All top level properties in an Item are
public. Properties of internal elements
are private.
00:16:05 Slide 15 colors red all public properties.
00:16:30 Slide 16 colors red all private properties.
Property ScopePart II, slides
17, 18
00:16:50 Pattern for declaring private properties:
Create a QtObject with id: internal
00:17:45 Avoid inheriting public members by
wrapping your base type in an Item and
expose only the properties your want to
make public.
States Part II, slides 20-23
00:19:35 States make your code more declarative.
00:19:55 Every Item has states.
00:20:55 Can change anchors in states to move
items around according to the state.
00:21:35 “when” clauses must be mutually
exclusive.
If they are not, the last one evaluated
wins.
States Part II, slides 24-25
00:23:25 Default state's name is "" (empty quotes).
These are the property settings in the QML
file outside the states declarations.
00:23:55 Use State's "extend" clause to use another
state as a base state to create sub-states.
"extend" re-uses children, not "when"
00:25:00 States do not need to be unwound. Set
common properties in the default state.
TransitionsPart II, slides 26-
28
00:26:10 Transitions allow you to control the order
of changes when changing states.
00:26:20 Example of Transitions.
00:27:50 * (asterisk) is the wildcard for a state.
Can use for from or to properties of
Transition.
00:28:40 If you do not set the target of an
animation, the animation will apply to all
items.
Creating ItemsPart II, slides
31-32
00:31:10 Procedural manner to create a
component is using createObject(parent,
bindings)
00:31:30 To create an item declaratively: Loader,
Repeater, ListView, GridView, PathView
00:32:35 Example of creating a dialog procedurally
using createComponent().
Procedural CreationPart II,
slides 32-33
00:33:00 Adding the binding elements in the
createObject call.
00:34:20 How to connect a signal to a function.
00:35:00 Example of how to declare a component
that can be created at runtime.
Declarative CreationPart II,
slides 34-37
00:36:30 Example of using a loader to create a
object at runtime. The Loader is
responsible for destroying the object
00:37:30 Example of using a repeater to create
objects.
00:38:20 Use modelData in the repeater.
00:38:40 Repeaters can use a lot of different data
models. See also Part IV, 7:45
Part II, Q & A
00:40:40 Almost always start with an Item when
extending a type.
00:41:55 If two rectangles need to be the same color,
bind one to the other and make a public alias
to the other instead of creating a top-level
property and binding both to it.
00:44:40 On slower processors, declarative component
creation is faster than procedural methods to
create elements.
Part II, Q & A
00:46:45 Prefer the declarative method for creating
components. This reduces the risk of a
catastrophic failure like missing resources.
00:48:55 GridView is limited with flexibility with Items.
You may have better control with GridView.
GridView is good for complex objects.
Part II, Q & A
00:51:00 Put states on the Item you are acting on.
Don't use states on a FocusScope, use states
inside an Item.
00:51:40 Use Repeaters for simple sources, such as
data coming from the internet.
00:54:10 Clear the component cache to reload all QML
Objects.
Model-View PatternPart III,
slide 5
00:03:00 Drive QML with a C++ backend. Separate
logic from UI.
00:04:15 Design back-end to be testable.
00:04:50 It is not recommended to directly affect
QML from C++, although it is possible.
C++ Integration Part III, slide 6
00:06:00 2 ways to expose C++ to QML: inject into
QML runtime (effectively singletons), or
expose C++ class to QML.
00:07:20 Everything the Qt company does, you can
do.
C++ IntegrationPart III, slide
6-9
00:07:40 Ingredients for a property: read & write
functions and notify signal.
00:08:00 Example of Qt code for C++ application
using Q_PROPERTY.
00:08:45 Q_PROPERTY does not expand into code;
it indicates to MOC what code to build.
C++ Slots Part III, slide 11-13
00:09:55 2 ways to make a callable function: slots or
Q_INVOKABLE. To MOC, they are
equivalent.
00:11:00 Q_INVOKABLE can return data. A QObject*
returned from a slot is owned by QML and
will be deleted. QObject* properties from
C++ are not deleted by QML.
00:12:00 Can call a static function to change this
behavior.
Exposing InstancesPart III,
slide 14-17
00:13:45 view->rootContext()->setContextProperty
injects a pointer into QML.
00:16:00 QObject* can be used as a property and
make a tree of properties.
00:16:30 Example of a QObject* property that can
be read from or written to -- there is only
a read function to get the pointer.
Complex PropertiesPart III,
slide 18-19
00:17:20 An Options class with base QObject. Now
has organization to properties and can be
navigated like a tree.
00:17:50 Example of using a QObject* as a tree:
maker.options.temp
Enum PropertiesPart III, slide
20-23
00:19:00 Discusses using Q_ENUMS, but use
Q_ENUM
00:19:30 If only need enums, use
qRegisterUncreatableType.
00:20:50 Shows using an enum from a C++ class.
00:21:20 You can convert the enum to a string.

QMetaEnum::fromType<T>().valueToKey(id);
Code Re-use Part III, slide 24-25
00:22:30 Different ways to reused C++ code with
QML. You only have 15ms to recalculate
bindings,
00:23:15 QML needs NOTIFY signals.
00:24:45 2 major ways. Add Q_PROPERTY macro
and Q_INVOKABLE to class if code it well
behaved. Otherwise write a wrapper.
Direct Re-usePart III, slide 26-31
00:25:20 Example of just adding macros that expose
functionality to QML
00:26:05 Issues. There is a check in MOC that all
notify signals appear in the same class and
have a Q_PROPERTY declaration. If the
signal appears in another class need to
make a SIGNAL-to-SIGNAL connection.
00:27:00 Creating a wrapper is easier if by
composition instead of inheritance.
Wrappers Part III, slide 32-34
00:27:50 QObjects cannot be used with Template-
based classes. Composition is necessary.
00:28:30 Maybe class does not follow get-set-notify
pattern.
00:29:00 Supervisor-control pattern. Class diagram.
Model - View Presenter.
Wrapper HeaderPart III, slide
35-36
00:30:00 Existing header for a template class with a
template-based callback system.
00:30:40 Create a number of wrapper classes
00:31:20 To deal with a template callback, register
callback with our class and emit the
corresponding signal.
00:32:00 QML ignores all parameters on signals
(SM: except in Connections element)
Wrapper HeaderPart III, slide
40-43
00:33:50 CANN-bus communication example. Data
continually broadcast -- do not store data
in label.
00:34:35 Model it in C++, read current value as it
comes in and store in a local cache and
emit a NOTIFY signal when value changes.
00:35:40 Example of a wrapper that passes through
an error message but caches changes to a
value.
Threading Part III, slide 44-46
00:37:20 Threading considerations. Wrap threaded
objects. Use cross-thread signals & slots to
your advantage.
00:38:00 BusData simply emits when new data has
arrived -- something else stores the value.
00:38:40 QObjects belong to a thread. Emitting a signal
looks at the thread context and if the same it's
a direct function call. But if the receiver is in a
different thread Qt posts an event with the
function to run and the parameter to pass to it.
Passing Data Part III, slide 47-48
00:40:40 Letting Qt marshall data between threads
removes the need to lock data.
00:41:00 To pass between threads, the data must
be QVariant compatible. (SM:
Q_DECLARE_METATYPE at end of file is not
necessary. Demo Q_GADGET. Use
qRegisterMetaType().) Need to be
copyable. Default constr, Assignment
operator and copy constructor. Pointer
types require care when deleting.
Implicit sharing Part III, slide 49
00:42:55 Use pointers if you have a large hunk of
data. Use QByteArray or any other that are
implicitly shared and are copy-on-write. You
can pass them and just a pointer is passed.
Copies a member pointer and a reference
count. At write time the data is detached
and copied. Data is only copied when
written to -- until it's just a pointer. Pass as a
const reference across signals. The reference
count is thread safe. Use to pass large
amounts of data.
Exposing C++ to QMLPart III,
slide 50-52
00:45:50 Use a C++ type if you want to create
multiple instances and qmlRegisterType().
00:47:30 Objects of QObject* properties are not
thread safe. Only classes that you can copy
are going to be truly thread-safe.
00:48:20 You do not need to register a type when
enjecting a QObject* into QML context
unless type information is need.
Part III, Q & A
00:49:10 Signals are just function calls. You can write
wrappers to call the signal like a function.
00:50:05 To use QML in a Widgets application, use
QQuickWidget. Can have problems with
keyboard focus.
Part III, Q & A
00:51:00 Inherit from QQuickItem or
QQuickPaintedItem to draw directly to the
screen.
00:52:10 Pointers returned by slots are owned by QML.
Can make a call to QML to say "this pointer
belongs to me".
Part III, Q & A
00:52:50 ProtoBus? Write a code generator in Python.
00:53:50 Set parent on a QObject to keep QML from
deleting it, but that keeps you from using
stack members.
Model-View-DelegatePart IV,
slide 4
00:03:25 Views in QML are Model-View-Delegate
pattern. The Delegate provides the user
interface for a cell.
Model-View-DelegatePart IV,
slide 5-6
00:04:15 All models are lists. Can use lists to make
fake tables and tree views using Desktop
Controls.
00:04:50 There is a model that allows making a
tree-based view.
00:05:05 Models have rows, columns and roles.
Roles are how you make complex data in
your view. Roles might be name, address,
phone number and photo.
Model Roles Part IV, slide 7
00:06:10 Delegates typically tightly bound to the
roles.
00:06:20 Make a reusable delegate with a QML
element with a number of properties in its
interface. Use this to decouple the
delegate from having knowledge of all the
roles.
Models Part IV, slide 8
00:07:45 All the models you can use:
QML ListModel
QML list<> property
JavaScript JSON
QQmlListProperty<Type>
QList<QObject*>
QAbstractItemModel* - the most powerful
model class in C++.
ListModel Part IV, slide 9-11
00:10:10 Problem with ListModel is that you must
copy the data into the ListModel.
00:10:40 Specialty model: XmlListModel - create a
model from XML that you might get from
web services. Can use XPath and XQuery.
00:11:05 Add-on package is available:
FolderListModel to make a list from a
directory on disk. Not a tree but helps to
make an explorer.
QML List Model Part IV, slide 12
00:11:30 Can make a list<> property.
00:12:10 Example in QtCreator which shows how to
make a bar chart.
00:13:30 list properties support C++ types.
JSON data Part IV, slide 13
00:13:55 QML supports JSON directly. Very useful
for web services.
C++ Qlist<QObject*>Part IV,
slide 14-15
00:14:50 QList<QObject*> is good to use if size of
list doesn't change.
00:16:30 When you change the size of the list, you
must destroy and create the entire list.
QAbstractItemModelPart IV,
slide 16-17
00:17:00 Best solution is to use the
QAbstractItemModel. Usually you can
wrap your C++ data. This is very efficient
for Views.
00:17:50 Can be confusing because it was designed
for tree lists.
00:18:35 The AbstractListModel is a subclass that
hides the tree-nature of the
QAbstractItemModel.
QAbstractItemModelPart IV,
slide 18-21
00:18:55 Wrap data, don't store data.
00:19:00 Necessities of a QAbstractListModel
implementation.
00:20:50 The roleNames function returns the
mapping from role to string name for
symbol in QML.
00:21:50 Example of returning rowCount and data.
QAbstractItemModelPart IV,
slide 21
00:23:00 Views are very efficient because we can
tell the view where things are inserted and
removed. If modified outside the view
area, there's nothing for the view to do.
00:23:45 Make sure to call the begin-end pairs
when modifying the list.
Which Model? Part IV, slide 22
00:24:10 Web Services: JSON or XmlListModel
00:24:45 C++ app, QAbstr.. or QList<QObject*>
00:25:10 For QML data driven app, use a list<>
property.
Keyboard HandlingPart IV, slide
24-25
00:26:30 Setting focus just sends keystrokes to an
element.
00:27:00 Keyboard navigation is done using
attached property: KeyNavigation, which
creates a linked list.
00:27:50 If you only specify one direction, Qt will
figure out the reverse direction
Focus PropertyPart IV, slide 26-
27
00:28:20 Only one element can have focus: true...
the last one that's set.
00:29:00 The focus property does not work as
expected. You cannot rely on focus
property. Easy to get 2 things focused
simultaneously. Use ActiveFocus for visual
appearance. Call forceActiveFocus() which
sets the focus to true and walk up the
heirarchy and get FocusScope elements to
release their focus.
FocusScope Part IV, slide 28-30
00:32:05 FocusScope pass focus on to their
children. Make all base classes where you
have keyboard navigation FocusScope
instead of Item.
00:33:50 Use the attached property, Keys, to handle
keyboard input where you have active
focus.
FocusScope Part IV, slide 31-34
00:34:40 To handle all keys, implement generic
Key.onPressed.
00:35:20 Keys when typed over an element that has
focus and then to it's parent if not
accepted. To stop propagation, set
accepted to true.
Performance Part IV, slide 36
00:37:55 Main thread has 16ms to complete work.
Back end must be as asynchronous as
possible.
00:38:50 Never call QApplication::processEvents().
This kind of worked with widgets. Never
call directly when using QML.
00:39:30 If populating data will be time consuming,
do in another thread.
Optimized bindingsPart IV,
slides 37-41
https://bugreports.qt.io/browse/QTBUG-49821
39:30-48:10 Is all about the optimized binding path
which is gone.
Use explicit typesPart IV, slide
42
00:48:35 Avoid type conversions. Do not use
property variant -- very slow. Use property
var. But prefer to use a specific type.
00:49:25 Modifying a list is expensive. Best to make
a copy of the list, modify in a for loop,
then assign after the for loop.
Cache results Part IV, slide 43
00:50:30 A lot of list lookups can be cached,
outperforming the… non-existent
optimized path.
Performance Part IV, slide 44-45
00:51:25 Do not over-update properties. Only emit
signals when value actually changes.
00:52:25 Delegates are a source of performance
problems. Avoid Loader. Avoid Shader
Effects.
00:53:20 Increase cache buffer for views to increase
performance.
Animations Part IV, slide 46
00:53:40 Avoid animating a property that is bound.
Use a second property and animate it.
Painting Part IV, slide 47
00:55:30 Avoid setting clip to true unless necessary.
00:55:50 Set visible to false for anything not on the
screen.
Startup PerformancePart IV,
slide 48-50
00:56:50 Load as little QML at startup, then use a
Loader item to load the rest of the
application.
00:57:45 Delete second screen or keep around?
00:58:10 Screens that are being kept around are
executing bindings.
Memory Usage Part IV, slide 51
00:58:40 QML uses about 80MB of resident data.
Adjust by keeping as few QML elements in
memory as possible.
Animations Part IV, slide 52-53
00:39:30 Animation is processed on the main CPU.
That will blow 30% of the CPU on a low-
end CPU.
01:00:30 If you just need a busy indicator, use
AnimatedImage. You can drop to 15fps
and this will greatly decrease CPU
overhead.
Part IV, Q & A
01:04:35 Delegates should not perform business logic
for the model. Delegates should call into the
model or another object that will manipulate
the model. This allows you to change the
delegate significantly and the business logic
will be used elsewhere.
Part IV, Q & A
01:05:55 QSortFilterProxyModel can only be used with
QAbstractItemModel.
Online Webinars:
https://www.ics.com/learning/webinars
Specifically:
Best Practices in Qt Quick/QML - Part I
Best Practices in Qt Quick/QML - Part II
Best Practices in Qt Quick/QML - Part III
Best Practices in Qt Quick/QML - Part IV
Slides:
https://www.slideshare.net/ICSinc/best-practices-i
n-qt-quick-qml-part-1
https://www.slideshare.net/ICSinc/best-practices-i
n-qt-quick-qml-part-ii
https://www.slideshare.net/ICSinc/best-practices-i
n-qt-quickqml-part-iii
https://www.slideshare.net/ICSinc/best-practices-i
n-qt-quickqml-part-iv

You might also like