Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
qtquick-bestpractices.qdoc
Go to the documentation of this file.
1
// Copyright (C) 2018 The Qt Company Ltd.
2
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
3
4
/*!
5
\page qtquick-bestpractices.html
6
\title Best Practices for QML and Qt Quick
7
\brief Lists best practices for working with QML and Qt Quick.
8
\ingroup best-practices
9
\ingroup explanations-programminglanguages
10
11
Despite all of the benefits that QML and Qt Quick offer, they can be
12
challenging in certain situations. The following sections elaborate on some of
13
the best practices that will help you get better results when developing
14
applications.
15
16
\section1 Custom UI Controls
17
18
A fluid and modern UI is key for any application's success in today's world, and
19
that's where QML makes so much sense for a designer or developer. Qt offers the
20
most basic UI controls that are necessary to create a fluid and modern-looking
21
UI. It is recommended to browse this list of UI controls before creating your
22
own custom UI control.
23
24
Besides these basic UI controls offered by Qt Quick itself, a rich set of UI
25
controls are also available with Qt Quick Controls. They cater to the most
26
common use cases without any change, and offer a lot more possibilities with their
27
customization options. In particular, Qt Quick Controls provides styling
28
options that align with the latest UI design trends. If these UI controls do not
29
satisfy your application's needs, only then it is recommended to create a
30
custom control.
31
32
You can use the controls when you design UIs in Qt Design Studio. In addition,
33
it provides timeline-based animations, visual effects, layouts, and a
34
live-preview for prototyping applications.
35
36
\section2 Related Information
37
\list
38
\li \l{Qt Quick Controls}
39
\li \l{Customizing Qt Quick Controls}
40
\li \l{Qt Quick}
41
\li \l{Qt Design Studio Manual}
42
\endlist
43
44
\omit
45
\section1 Keep it Short and Simple or "KiSS"
46
47
QML being a declarative language, a lot of the details are worked out by the underlying
48
engine. So it is important for any QML application, especially one with a
49
larger codebase, to have its code organized in smaller and simpler \c .qml files.
50
51
TODO: need a few snippet or example applications that showcase this.
52
\endomit
53
54
\section1 Coding Conventions
55
56
See \l{QML Coding Conventions}.
57
58
\section1 Bundle Application Resources
59
60
Most applications depend on resources such as images and icons to provide a
61
rich user experience. It can often be a challenge to make these resources
62
available to the application regardless of the target OS. Most popular OS-es
63
employ stricter security policies that restrict access to the file system,
64
making it harder to load these resources. As an alternative, Qt offers its own
65
\l {The Qt Resource System}{resource system} that is built into the
66
application binary, enabling access to the application's resources regardless
67
of the target OS.
68
69
For example, consider the following project directory structure:
70
71
\badcode
72
MyModule
73
├── images
74
│ ├── image1.png
75
│ └── image2.png
76
├── CMakeLists.txt
77
└── main.qml
78
\endcode
79
80
You may represent this structure as a \l{qt_add_qml_module}{CMake QML Module} in the following way:
81
82
\code
83
qt_add_qml_module(my_module
84
URI MyModule
85
VERSION 1.0
86
QML_FILES
87
main.qml
88
RESOURCES
89
images/image1.png
90
images/image2.png
91
# ...
92
)
93
\endcode
94
95
All QML files listed under \c {QML_FILES} will automatically get compiled \l {Ahead-of-Time Compilation}{ahead of time}.
96
97
You should keep the QML files in the same directory as the CMakeLists.txt with
98
the qt_add_qml_module. Otherwise their \l{The Implicit Import}{implicit imports}
99
will be different from the \l{QML Modules} they belong to. This is a frequent
100
source of mistakes.
101
102
\section2 Related Information
103
\list
104
\li \l{The Qt Resource System}
105
\endlist
106
107
\section1 Separate UI from Business Logic
108
109
One of the key goals that most application developers want to achieve is to
110
create a maintainable application. One of the ways to achieve this goal is
111
to separate the user interface from the business logic. The following are a few
112
reasons why an application's UI should be written in QML:
113
114
\list
115
\li Declarative languages are strongly suited for defining UIs.
116
\li QML code is simpler to write, as it is less verbose than C++, and is not
117
strongly typed. This also results in it being an excellent language to
118
prototype in, a quality that is vital when collaborating with designers,
119
for example.
120
\li JavaScript can easily be used in QML to respond to events.
121
\endlist
122
123
Being a strongly typed language, C++ is best suited for an application's
124
business logic. Typically, such code performs tasks such as complex calculations
125
or data processing, which are faster in C++ than QML.
126
127
Qt offers various approaches to integrate QML and C++ code in an application.
128
A typical use case is displaying a list of data in a user interface.
129
If the data set is static, simple, and/or small, a model written in QML can be
130
sufficient.
131
132
The following snippet demonstrates examples of models written in QML:
133
134
\qml
135
model: [ "Item 1", "Item 2", "Item 3" ]
136
137
model: 10
138
\endqml
139
140
Use \l {QAbstractItemModel Subclass}{C++} for dynamic data sets that are large
141
or frequently modified.
142
143
\section2 Exposing Data from C++ to QML
144
145
Refactoring QML is a lot easier than refactoring C++, so in order to make
146
maintenance pain-free, we should strive to keep C++ types unaware of QML as
147
much as possible. This can be achieved by "pushing" references to C++ types
148
into QML.
149
150
This can be done by using \l {Required properties}{required properties} and
151
setting them via \l QQmlApplicationEngine::setInitialProperties. It is also
152
possible to create one or multiple \l {QML_SINGLETON}{singletons} which will
153
return all the data the C++ side wants to provide to QML.
154
155
With this approach, the C++ remains unchanged in the event that the QML needs
156
to be refactored in the future.
157
158
For a quick guide to choosing the correct approach to expose C++ types to QML,
159
see \l {Choosing the Correct Integration Method Between C++ and QML}.
160
161
\section2 Related Information
162
\list
163
\li \l{Writing QML Extensions with C++}
164
{Writing QML Extensions with C++ Tutorial}
165
\li \l{Qt Quick Controls - Chat Tutorial}{Chat application tutorial}
166
\endlist
167
168
\section1 Using Qt Design Studio
169
170
Qt Design Studio uses UI files that have the filename extension \e {.ui.qml}
171
to separate the visual parts of the UI from the UI logic you implement in
172
\e {.qml} files. You should edit UI files only in the \uicontrol {2D} view in
173
Qt Design Studio. If you use some other tool to add code that Qt Design Studio
174
does not support, it displays error messages. Fix the errors to enable visual
175
editing of the UI files again. Typically, you should move the unsupported code
176
to a \e {.qml} file.
177
178
\section2 Related Information
179
180
\list
181
\li \l{Qt Design Studio: UI Files}
182
\endlist
183
184
\section1 Using Qt Quick Views
185
186
\section2 Store State in Models
187
188
See \l {Avoid Storing State in Delegates}.
189
190
\section1 Using Qt Quick Layouts
191
192
Qt offers Qt Quick Layouts to arrange Qt Quick items visually in a layout.
193
Unlike its alternative, the item positioners, the Qt Quick Layouts can also
194
resize its children on window resize. Although Qt Quick Layouts are often
195
the desired choice for most use cases, the following \e dos and \e{don'ts}
196
must be considered while using them:
197
198
\section2 Dos
199
200
\list
201
\li Use \l {Item::}{anchors} or the \l {Item::}{width} and \l {Item::}{height}
202
properties to specify the size of the layout against its non-layout parent
203
item.
204
\li Use the \l Layout attached property to set the size and alignment
205
attributes of the layout's immediate children.
206
\endlist
207
208
\section2 Don'ts
209
210
\list
211
\li Do not define preferred sizes for items that provide implicitWidth and
212
implicitHeight, unless their implicit sizes are not satisfactory.
213
\li Do not use anchors on an item that is an immediate child of a layout.
214
Instead, use \c Layout.preferredWidth and \c Layout.preferredHeight:
215
216
\snippet qml/windowconstraints.qml rowlayout
217
\endlist
218
219
\note Layouts and anchors are both types of objects that take more memory and
220
instantiation time. Avoid using them (especially in list and table delegates,
221
and styles for controls) when simple bindings to x, y, width, and height
222
properties are enough.
223
224
\section2 Related Information
225
226
\list
227
\li \l{Item Positioners}
228
\li \l{Qt Quick Layouts Overview}
229
\endlist
230
231
\section1 Type Safety
232
233
When declaring properties in QML, it's easy and convenient to use the "var" type:
234
235
\code
236
property var name
237
property var size
238
property var optionsMenu
239
\endcode
240
241
However, this approach has several disadvantages:
242
\list
243
\li If a value with the wrong type is assigned, the error reported will point
244
to the location of the property declaration, as opposed to the location
245
where the property was assigned to. This slows down the development
246
process by making it more difficult to track down errors.
247
\li Static anaylsis to catch errors like the ones mentioned above is not
248
possible.
249
\li The actual underlying type of the property is not always immediately clear
250
to the reader.
251
\endlist
252
253
Instead, always use the actual type where possible:
254
255
\code
256
property string name
257
property int size
258
property MyMenu optionsMenu
259
\endcode
260
261
\section1 Property change signals
262
263
Prefer using the explicit interaction signals over the value changed signals to
264
avoid subtle bugs.
265
266
Using \c {valueChanged} can lead to event cascades where the value is constantly
267
changed because it is somehow rounded or normalized.
268
269
Using explicit interaction signals alone avoids this whole class of issues.
270
271
For example, \l Slider has these similar signals: \l {Slider::}{moved} and
272
\c {valueChanged}.
273
274
\qml
275
Slider {
276
value: someValueFromBackend
277
278
onValueChanged: pushToBackend(value)
279
// or
280
onMoved: pushToBackend(value)
281
}
282
\endqml
283
284
Both cases look similar, and you may want to use \c {valueChanged}.
285
286
Developers often overlook the fact that the \l Slider can automatically change
287
its value, for example, because of clamping to minimum/maximum values or
288
rounding. In this case, the \c {valueChanged} signal is emitted. If you use the
289
\c {valueChanged} signal, you may notice it is emitted at unexpected moments.
290
291
To avoid possible issues, use an interaction signal: the signal that is emitted
292
when user interacts with the control. In this example, if you use the
293
\l {Slider::}{moved} signal, the slot will only be triggered if the user
294
changes the control.
295
296
\section1 Performance
297
298
For information on performance in QML and Qt Quick,
299
see \l {QML Performance Considerations And Suggestions}.
300
301
\section1 Prefer Declarative Bindings Over Imperative Assignments
302
303
In QML, it's possible to use imperative JavaScript code to perform tasks
304
such as responding to input events, send data over a network, and so on.
305
Imperative code has an important place in QML, but it's also important
306
to be aware of when not to use it.
307
308
For example, consider the following imperative assignment:
309
310
\code
311
Rectangle {
312
Component.onCompleted: color = "red"
313
}
314
\endcode
315
316
This has the following disadvantages:
317
318
\list
319
\li It's slow. The color property will first be evaluated with a
320
default-constructed value, and then again with "red" later on.
321
\li It delays errors that could be found at build time to run time, slowing
322
down the development process.
323
\li It overwrites any declarative binding that was in place. In most cases this
324
is intended, but sometimes it can be unintentional.
325
See \l {Debugging overwriting of bindings} for more information.
326
\li It interferes with tooling; Qt Quick Designer, for example, doesn't support
327
JavaScript.
328
\endlist
329
330
The code can be rewritten to be a declarative binding instead:
331
332
\code
333
Rectangle {
334
color: "red"
335
}
336
\endcode
337
338
\section1 Don't store state in delegates
339
340
Don't store a state in a delegate. The issue here is that the delegate is
341
created and destroyed multiple times, so the saved state will be lost.
342
343
\qml
344
// Wrong approach:
345
ListView {
346
// ...
347
348
delegate: Button {
349
// ...
350
property bool someStateProperty
351
onClicked: someStateProperty = true
352
}
353
}
354
\endqml
355
356
Instead, store the state outside of the delegate. For example, in a model.
357
When the delegate is destroyed, the saved state is not lost.
358
359
\qml
360
// Right approach:
361
ListView {
362
// ...
363
364
delegate: Button {
365
// ...
366
onClicked: model.someStateProperty = true
367
}
368
}
369
\endqml
370
371
\section1 Make user-facing strings translatable
372
373
It is recommended to make user-facing strings translatable from the beginning.
374
See \l {Writing Source Code for Translation}.
375
376
\qml
377
ToolButton {
378
id: selectionToolButton
379
// ...
380
icon.source: "qrc:/images/selection.png"
381
382
Tooltip.Text: qsTr("Select pixels within an area and move them")
383
384
onClicked: canvas.tool = ImageCanvas.SelectionTool
385
}
386
\endqml
387
388
\section1 Do not customize native styles
389
390
Native styles (Windows and macOS styles) don't support customization.
391
Ensure you don't customize a native style.
392
393
\qml *
394
// Wrong approach:
395
import QtQuick.Controls.Windows
396
397
// Don't customize a native style
398
Button {
399
background: Rectangle { /\1...\1/ }
400
}
401
\endqml
402
403
\include customizing-native-styles.qdocinc
404
405
\qml *
406
// Right approach:
407
import QtQuick.Controls.Basic
408
409
// You can customize a commonly available style
410
Button {
411
background: Rectangle { /\1...\1/ }
412
}
413
\endqml
414
415
\section1 Tools and Utilities
416
417
For information on useful tools and utilies that make working with QML and
418
Qt Quick easier, see \l {Qt Quick Tools and Utilities}.
419
420
\section1 Scene Graph
421
422
For information on Qt Quick's scene graph, see \l {Qt Quick Scene Graph}.
423
424
\section1 Scalable User Interfaces
425
426
As display resolutions improve, a scalable application UI becomes more and
427
more important. One of the approaches to achieve this is to maintain several
428
copies of the UI for different screen resolutions, and load the appropriate one
429
depending on the available resolution. Although this works pretty
430
well, it adds to the maintenance overhead.
431
432
Qt offers a better solution to this problem and recommends the application
433
developers to follow these tips:
434
435
\list
436
\li Use anchors or the Qt Quick Layouts module to lay out the visual items.
437
\li Do not specify explicit width and height for a visual item.
438
\li Provide UI resources such as images and icons for each display resolution
439
that your application supports. The Qt Quick Controls gallery example
440
demonstrates this well by providing the \c qt-logo.png for \c @2x, \c @3x,
441
and \c @4x resolutions, enabling the application to cater to high
442
resolution displays. Qt automatically chooses the appropriate
443
image that is suitable for the given display, provided the high DPI scaling
444
feature is explicitly enabled.
445
\li Use SVG images for small icons. While larger SVGs can be slow to render,
446
small ones work well. Vector images avoid the need to provide several
447
versions of an image, as is necessary with bitmap images.
448
\li Use font-based icons, such as Font Awesome. These scale to any display
449
resolution, and also allow colorization. The
450
Qt Quick Controls Text Editor example demonstrates this well.
451
\endlist
452
453
With this in place, your application's UI should scale depending
454
on the display resolution on offer.
455
456
\image qtquickcontrols-gallery-welcome.png
457
458
\section2 Related Information
459
460
\list
461
\li \l{Qt Quick Controls - Gallery}{Gallery example}
462
\li \l{Qt Quick Controls - Text Editor}{Text Editor example}
463
\li \l{Font Awesome}
464
\li \l{Scalability}
465
\li \l{High DPI}
466
\endlist
467
*/
qtdeclarative
src
quick
doc
src
guidelines
qtquick-bestpractices.qdoc
Generated on
for Qt by
1.14.0