Qt-QML Best of Best ICS Webinars
Qt-QML Best of Best ICS Webinars
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…
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