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