Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Toggle main menu visibility
Loading...
Searching...
No Matches
qqmlsettings.cpp
Go to the documentation of this file.
1
// Copyright (C) 2016 The Qt Company Ltd.
2
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
// Qt-Security score:significant reason:default
4
5
#
include
"qqmlsettings_p.h"
6
#
include
<
qcoreevent
.
h
>
7
#
include
<
qcoreapplication
.
h
>
8
#
include
<
qloggingcategory
.
h
>
9
#
include
<
qsettings
.
h
>
10
#
include
<
qpointer
.
h
>
11
#
include
<
qjsvalue
.
h
>
12
#
include
<
qqmlinfo
.
h
>
13
#
include
<
qdebug
.
h
>
14
#
include
<
qhash
.
h
>
15
16
QT_BEGIN_NAMESPACE
17
18
/*!
19
\qmlmodule Qt.labs.settings 1.0
20
\title Qt Labs Settings QML Types
21
\ingroup qmlmodules
22
\deprecated [6.5] Use \l [QML] {QtCore::}{Settings} from Qt Qml Core instead.
23
\brief Provides persistent platform-independent application settings.
24
25
To use this module, import the module with the following line:
26
27
\code
28
import Qt.labs.settings
29
\endcode
30
*/
31
32
/*!
33
\qmltype Settings
34
//! \nativetype QQmlSettingsLabs
35
\inqmlmodule Qt.labs.settings
36
\ingroup settings
37
\deprecated [6.5] Use \l [QML] {QtCore::}{Settings} from Qt Qml Core instead.
38
\brief Provides persistent platform-independent application settings.
39
40
The Settings type provides persistent platform-independent application settings.
41
42
\note This type is made available by importing the \b Qt.labs.settings module.
43
\e {Types in the Qt.labs module are not guaranteed to remain compatible
44
in future versions.}
45
46
Users normally expect an application to remember its settings (window sizes
47
and positions, options, etc.) across sessions. The Settings type enables you
48
to save and restore such application settings with the minimum of effort.
49
50
Individual setting values are specified by declaring properties within a
51
Settings element. All \l {QML Value Types}{value type} properties are
52
supported. The recommended approach is to use property aliases in order
53
to get automatic property updates both ways. The following example shows
54
how to use Settings to store and restore the geometry of a window.
55
56
\qml
57
import QtQuick.Window
58
import Qt.labs.settings
59
60
Window {
61
id: window
62
63
width: 800
64
height: 600
65
66
Settings {
67
property alias x: window.x
68
property alias y: window.y
69
property alias width: window.width
70
property alias height: window.height
71
}
72
}
73
\endqml
74
75
At first application startup, the window gets default dimensions specified
76
as 800x600. Notice that no default position is specified - we let the window
77
manager handle that. Later when the window geometry changes, new values will
78
be automatically stored to the persistent settings. The second application
79
run will get initial values from the persistent settings, bringing the window
80
back to the previous position and size.
81
82
A fully declarative syntax, achieved by using property aliases, comes at the
83
cost of storing persistent settings whenever the values of aliased properties
84
change. Normal properties can be used to gain more fine-grained control over
85
storing the persistent settings. The following example illustrates how to save
86
a setting on component destruction.
87
88
\qml
89
import QtQuick
90
import Qt.labs.settings
91
92
Item {
93
id: page
94
95
state: settings.state
96
97
states: [
98
State {
99
name: "active"
100
// ...
101
},
102
State {
103
name: "inactive"
104
// ...
105
}
106
]
107
108
Settings {
109
id: settings
110
property string state: "active"
111
}
112
113
Component.onDestruction: {
114
settings.state = page.state
115
}
116
}
117
\endqml
118
119
Notice how the default value is now specified in the persistent setting property,
120
and the actual property is bound to the setting in order to get the initial value
121
from the persistent settings.
122
123
\section1 Application Identifiers
124
125
Application specific settings are identified by providing application
126
\l {QCoreApplication::applicationName}{name},
127
\l {QCoreApplication::organizationName}{organization} and
128
\l {QCoreApplication::organizationDomain}{domain}, or by specifying
129
\l fileName.
130
131
\code
132
#include <QGuiApplication>
133
#include <QQmlApplicationEngine>
134
135
int main(int argc, char *argv[])
136
{
137
QGuiApplication app(argc, argv);
138
app.setOrganizationName("Some Company");
139
app.setOrganizationDomain("somecompany.com");
140
app.setApplicationName("Amazing Application");
141
142
QQmlApplicationEngine engine("main.qml");
143
return app.exec();
144
}
145
\endcode
146
147
These are typically specified in C++ in the beginning of \c main(),
148
but can also be controlled in QML via the following properties:
149
\list
150
\li \l {Qt::application}{Qt.application.name},
151
\li \l {Qt::application}{Qt.application.organization} and
152
\li \l {Qt::application}{Qt.application.domain}.
153
\endlist
154
155
\section1 Categories
156
157
Application settings may be divided into logical categories by specifying
158
a category name via the \l category property. Using logical categories not
159
only provides a cleaner settings structure, but also prevents possible
160
conflicts between setting keys.
161
162
If several categories are required, use several Settings objects, each with
163
their own category:
164
165
\qml
166
Item {
167
id: panel
168
169
visible: true
170
171
Settings {
172
category: "OutputPanel"
173
property alias visible: panel.visible
174
// ...
175
}
176
177
Settings {
178
category: "General"
179
property alias fontSize: fontSizeSpinBox.value
180
// ...
181
}
182
}
183
\endqml
184
185
Instead of ensuring that all settings in the application have unique names,
186
the settings can be divided into unique categories that may then contain
187
settings using the same names that are used in other categories - without
188
a conflict.
189
190
\section1 Notes
191
192
The current implementation is based on \l QSettings. This imposes certain
193
limitations, such as missing change notifications. Writing a setting value
194
using one instance of Settings does not update the value in another Settings
195
instance, even if they are referring to the same setting in the same category.
196
197
The information is stored in the system registry on Windows, and in XML
198
preferences files on \macos. On other Unix systems, in the absence of a
199
standard, INI text files are used. See \l QSettings documentation for
200
more details.
201
202
\sa {QtCore::}{Settings}, QSettings
203
*/
204
205
Q_STATIC_LOGGING_CATEGORY
(lcSettings,
"qt.labs.settings"
)
206
207
static
const
int
settingsWriteDelay
= 500;
208
209
class
QQmlSettingsLabsPrivate
210
{
211
Q_DECLARE_PUBLIC(QQmlSettingsLabs)
212
213
public
:
214
QQmlSettingsLabsPrivate
();
215
216
QSettings
*
instance
()
const
;
217
218
void
init
();
219
void
reset
();
220
221
void
load
();
222
void
store
();
223
224
void
_q_propertyChanged
();
225
QVariant
readProperty
(
const
QMetaProperty &property)
const
;
226
227
QQmlSettingsLabs
*
q_ptr
=
nullptr
;
228
int
timerId
= 0;
229
bool
initialized
=
false
;
230
QString
category
;
231
QString
fileName
;
232
mutable
QPointer
<
QSettings
>
settings
;
233
QHash
<
const
char
*, QVariant>
changedProperties
;
234
};
235
236
QQmlSettingsLabsPrivate
::QQmlSettingsLabsPrivate() {}
237
238
QSettings
*
QQmlSettingsLabsPrivate
::
instance
()
const
239
{
240
if
(!settings) {
241
QQmlSettingsLabs *q =
const_cast
<QQmlSettingsLabs*>(q_func());
242
settings = fileName.isEmpty() ?
new
QSettings(q) :
new
QSettings(fileName, QSettings::IniFormat, q);
243
if
(settings->status() != QSettings::NoError) {
244
// TODO: can't print out the enum due to the following error:
245
// error: C2666: 'QQmlInfo::operator <<': 15 overloads have similar conversions
246
qmlWarning(q) <<
"Failed to initialize QSettings instance. Status code is: "
<<
int
(settings->status());
247
248
if
(settings->status() == QSettings::AccessError) {
249
QList<QString> missingIdentifiers;
250
if
(QCoreApplication::organizationName().isEmpty())
251
missingIdentifiers.append(QLatin1String(
"organizationName"
));
252
if
(QCoreApplication::organizationDomain().isEmpty())
253
missingIdentifiers.append(QLatin1String(
"organizationDomain"
));
254
if
(QCoreApplication::applicationName().isEmpty())
255
missingIdentifiers.append(QLatin1String(
"applicationName"
));
256
257
if
(!missingIdentifiers.isEmpty())
258
qmlWarning(q) <<
"The following application identifiers have not been set: "
<< missingIdentifiers;
259
}
260
return
settings;
261
}
262
263
if
(!category.isEmpty())
264
settings->beginGroup(category);
265
if
(initialized)
266
q->d_func()->load();
267
}
268
return
settings;
269
}
270
271
void
QQmlSettingsLabsPrivate
::
init
()
272
{
273
if
(!
initialized
) {
274
qCDebug
(lcSettings) <<
"QQmlSettingsLabs: stored at"
<< instance()->fileName();
275
load
(
)
;
276
initialized
=
true
;
277
}
278
}
279
280
void
QQmlSettingsLabsPrivate
::
reset
()
281
{
282
if
(initialized && settings && !changedProperties.isEmpty())
283
store
(
)
;
284
delete
settings;
285
}
286
287
void
QQmlSettingsLabsPrivate
::
load
()
288
{
289
Q_Q(QQmlSettingsLabs);
290
const
QMetaObject *mo = q->metaObject();
291
const
int
offset = mo->propertyOffset();
292
const
int
count = mo->propertyCount();
293
294
// don't save built-in properties if there aren't any qml properties
295
if
(offset == 1)
296
return
;
297
298
for
(
int
i = offset; i < count; ++i) {
299
QMetaProperty property = mo->property(i);
300
const
QString propertyName = QString::fromUtf8(property.name());
301
302
const
QVariant previousValue = readProperty(property);
303
const
QVariant currentValue = instance()->value(propertyName,
304
previousValue);
305
306
if
(!currentValue.isNull() && (!previousValue.isValid()
307
|| (currentValue.canConvert(previousValue.metaType())
308
&& previousValue != currentValue))) {
309
property.write(q, currentValue);
310
qCDebug
(lcSettings) <<
"QQmlSettingsLabs: load"
<< property.name() <<
"setting:"
<< currentValue <<
"default:"
<< previousValue;
311
}
312
313
// ensure that a non-existent setting gets written
314
// even if the property wouldn't change later
315
if
(!instance()->contains(propertyName))
316
_q_propertyChanged
(
)
;
317
318
// setup change notifications on first load
319
if
(!
initialized
&& property.hasNotifySignal()) {
320
static
const
int
propertyChangedIndex = mo->indexOfSlot(
"_q_propertyChanged()"
);
321
QMetaObject::connect(q, property.notifySignalIndex(), q, propertyChangedIndex);
322
}
323
}
324
}
325
326
void
QQmlSettingsLabsPrivate
::
store
()
327
{
328
QHash<
const
char
*, QVariant>::const_iterator it = changedProperties.constBegin();
329
while
(it != changedProperties.constEnd()) {
330
instance()->setValue(QString::fromUtf8(it.key()), it.value());
331
qCDebug
(lcSettings) <<
"QQmlSettingsLabs: store"
<< it.key() <<
":"
<< it.value();
332
++it;
333
}
334
changedProperties.clear();
335
}
336
337
void
QQmlSettingsLabsPrivate
::
_q_propertyChanged
()
338
{
339
Q_Q(QQmlSettingsLabs);
340
const
QMetaObject *mo = q->metaObject();
341
const
int
offset = mo->propertyOffset();
342
const
int
count = mo->propertyCount();
343
for
(
int
i = offset; i < count; ++i) {
344
const
QMetaProperty &property = mo->property(i);
345
const
QVariant value = readProperty(property);
346
changedProperties.insert(property.name(), value);
347
qCDebug
(lcSettings) <<
"QQmlSettingsLabs: cache"
<< property.name() <<
":"
<< value;
348
}
349
if
(timerId != 0)
350
q->killTimer(timerId);
351
timerId
= q->startTimer(settingsWriteDelay);
352
}
353
354
QVariant
QQmlSettingsLabsPrivate
::
readProperty
(
const
QMetaProperty &property)
const
355
{
356
Q_Q(
const
QQmlSettingsLabs);
357
QVariant var = property.read(q);
358
if
(var.metaType() == QMetaType::fromType<QJSValue>())
359
var = var.value<QJSValue>().toVariant();
360
return
var;
361
}
362
363
QQmlSettingsLabs::QQmlSettingsLabs(QObject *parent)
364
: QObject(parent), d_ptr(
new
QQmlSettingsLabsPrivate)
365
{
366
Q_D(QQmlSettingsLabs);
367
d->q_ptr =
this
;
368
}
369
370
QQmlSettingsLabs::~QQmlSettingsLabs()
371
{
372
Q_D(QQmlSettingsLabs);
373
d->reset();
// flush pending changes
374
}
375
376
/*!
377
\qmlproperty string Settings::category
378
379
This property holds the name of the settings category.
380
381
Categories can be used to group related settings together.
382
*/
383
QString QQmlSettingsLabs::category()
const
384
{
385
Q_D(
const
QQmlSettingsLabs);
386
return
d->category;
387
}
388
389
void
QQmlSettingsLabs::setCategory(
const
QString &category)
390
{
391
Q_D(QQmlSettingsLabs);
392
if
(d->category != category) {
393
d->reset();
394
d->category = category;
395
if
(d->initialized)
396
d->load();
397
}
398
}
399
400
/*!
401
\qmlproperty string Settings::fileName
402
403
This property holds the path to the settings file. If the file doesn't
404
already exist, it is created.
405
406
\since Qt 5.12
407
408
\sa QSettings::fileName, QSettings::IniFormat
409
*/
410
QString QQmlSettingsLabs::fileName()
const
411
{
412
Q_D(
const
QQmlSettingsLabs);
413
return
d->fileName;
414
}
415
416
void
QQmlSettingsLabs::setFileName(
const
QString &fileName)
417
{
418
Q_D(QQmlSettingsLabs);
419
if
(d->fileName != fileName) {
420
d->reset();
421
d->fileName = fileName;
422
if
(d->initialized)
423
d->load();
424
}
425
}
426
427
/*!
428
\qmlmethod var Settings::value(string key, var defaultValue)
429
430
Returns the value for setting \a key. If the setting doesn't exist,
431
returns \a defaultValue.
432
433
\since Qt 5.12
434
435
\sa QSettings::value
436
*/
437
QVariant QQmlSettingsLabs::value(
const
QString &key,
const
QVariant &defaultValue)
const
438
{
439
Q_D(
const
QQmlSettingsLabs);
440
return
d->instance()->value(key, defaultValue);
441
}
442
443
/*!
444
\qmlmethod void Settings::setValue(string key, var value)
445
446
Sets the value of setting \a key to \a value. If the key already exists,
447
the previous value is overwritten.
448
449
\since Qt 5.12
450
451
\sa QSettings::setValue
452
*/
453
void
QQmlSettingsLabs::setValue(
const
QString &key,
const
QVariant &value)
454
{
455
Q_D(
const
QQmlSettingsLabs);
456
d->instance()->setValue(key, value);
457
qCDebug
(lcSettings) <<
"QQmlSettingsLabs: setValue"
<< key <<
":"
<< value;
458
}
459
460
/*!
461
\qmlmethod void Settings::sync()
462
463
Writes any unsaved changes to permanent storage, and reloads any
464
settings that have been changed in the meantime by another
465
application.
466
467
This function is called automatically from QSettings's destructor and
468
by the event loop at regular intervals, so you normally don't need to
469
call it yourself.
470
471
\sa QSettings::sync
472
*/
473
void
QQmlSettingsLabs::sync()
474
{
475
Q_D(QQmlSettingsLabs);
476
d->instance()->sync();
477
}
478
479
void
QQmlSettingsLabs::classBegin()
480
{
481
}
482
483
void
QQmlSettingsLabs::componentComplete()
484
{
485
Q_D(QQmlSettingsLabs);
486
d->init();
487
qmlWarning(
this
) <<
"The Settings type from Qt.labs.settings is deprecated"
488
" and will be removed in a future release. Please use "
489
"the one from QtCore instead."
;
490
}
491
492
void
QQmlSettingsLabs::timerEvent(QTimerEvent *event)
493
{
494
Q_D(QQmlSettingsLabs);
495
if
(event->timerId() == d->timerId) {
496
killTimer(d->timerId);
497
d->timerId = 0;
498
499
d->store();
500
}
501
QObject::timerEvent(event);
502
}
503
504
QT_END_NAMESPACE
505
506
#
include
"moc_qqmlsettings_p.cpp"
QHash
\inmodule QtCore
Definition
qhash.h:844
QQmlSettingsLabsPrivate
Definition
qqmlsettings.cpp:210
QQmlSettingsLabsPrivate::_q_propertyChanged
void _q_propertyChanged()
Definition
qqmlsettings.cpp:337
QQmlSettingsLabsPrivate::load
void load()
Definition
qqmlsettings.cpp:287
QQmlSettingsLabsPrivate::instance
QSettings * instance() const
Definition
qqmlsettings.cpp:238
QQmlSettingsLabsPrivate::initialized
bool initialized
Definition
qqmlsettings.cpp:229
QQmlSettingsLabsPrivate::settings
QPointer< QSettings > settings
Definition
qqmlsettings.cpp:232
QQmlSettingsLabsPrivate::init
void init()
Definition
qqmlsettings.cpp:271
QQmlSettingsLabsPrivate::category
QString category
Definition
qqmlsettings.cpp:230
QQmlSettingsLabsPrivate::q_ptr
QQmlSettingsLabs * q_ptr
Definition
qqmlsettings.cpp:227
QQmlSettingsLabsPrivate::readProperty
QVariant readProperty(const QMetaProperty &property) const
Definition
qqmlsettings.cpp:354
QQmlSettingsLabsPrivate::timerId
int timerId
Definition
qqmlsettings.cpp:228
QQmlSettingsLabsPrivate::reset
void reset()
Definition
qqmlsettings.cpp:280
QQmlSettingsLabsPrivate::store
void store()
Definition
qqmlsettings.cpp:326
QQmlSettingsLabsPrivate::changedProperties
QHash< const char *, QVariant > changedProperties
Definition
qqmlsettings.cpp:233
QQmlSettingsLabsPrivate::fileName
QString fileName
Definition
qqmlsettings.cpp:231
settingsWriteDelay
static constexpr auto settingsWriteDelay
Definition
qqmlsettings.cpp:210
QT_BEGIN_NAMESPACE
Combined button and popup list for selecting options.
Definition
qsequentialanimationgroup.cpp:47
qCDebug
#define qCDebug(category,...)
Definition
qloggingcategory.h:162
Q_STATIC_LOGGING_CATEGORY
#define Q_STATIC_LOGGING_CATEGORY(name,...)
Definition
qloggingcategory.h:154
qtdeclarative
src
labs
settings
qqmlsettings.cpp
Generated on
for Qt by
1.18.0