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
qqmlpropertymap.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
4
5
#
include
"qqmlpropertymap.h"
6
7
#
include
<
private
/
qmetaobjectbuilder_p
.
h
>
8
#
include
<
private
/
qqmlopenmetaobject_p
.
h
>
9
10
#
include
<
QDebug
>
11
12
QT_BEGIN_NAMESPACE
13
14
//QQmlPropertyMapMetaObject lets us listen for changes coming from QML
15
//so we can emit the changed signal.
16
class
QQmlPropertyMapMetaObject
:
public
QQmlOpenMetaObject
17
{
18
public
:
19
QQmlPropertyMapMetaObject
(QQmlPropertyMap *obj,
QQmlPropertyMapPrivate
*objPriv,
const
QMetaObject *staticMetaObject);
20
21
protected
:
22
QVariant
propertyWriteValue
(
int
,
const
QVariant &)
override
;
23
void
propertyWritten
(
int
index)
override
;
24
void
propertyCreated
(
int
, QMetaPropertyBuilder &)
override
;
25
26
const
QString
&
propertyName
(
int
index);
27
28
private
:
29
QQmlPropertyMap *map;
30
QQmlPropertyMapPrivate
*priv;
31
};
32
33
class
QQmlPropertyMapPrivate
:
public
QObjectPrivate
34
{
35
Q_DECLARE_PUBLIC(QQmlPropertyMap)
36
public
:
37
QQmlPropertyMapMetaObject
*
mo
;
38
QStringList
keys
;
39
40
QVariant
updateValue
(
const
QString &key,
const
QVariant &input);
41
void
emitChanged
(
const
QString &key,
const
QVariant &value);
42
static
bool
validKeyName
(
const
QString& name);
43
44
const
QString
&
propertyName
(
int
index)
const
;
45
};
46
47
bool
QQmlPropertyMapPrivate
::validKeyName(
const
QString& name)
48
{
49
//The following strings shouldn't be used as property names
50
return
name != QLatin1String(
"keys"
)
51
&& name != QLatin1String(
"valueChanged"
)
52
&& name != QLatin1String(
"QObject"
)
53
&& name != QLatin1String(
"destroyed"
)
54
&& name != QLatin1String(
"deleteLater"
);
55
}
56
57
QVariant
QQmlPropertyMapPrivate
::
updateValue
(
const
QString &key,
const
QVariant &input)
58
{
59
Q_Q(QQmlPropertyMap);
60
return
q->updateValue(key, input);
61
}
62
63
void
QQmlPropertyMapPrivate
::
emitChanged
(
const
QString &key,
const
QVariant &value)
64
{
65
Q_Q(QQmlPropertyMap);
66
emit q->valueChanged(key, value);
67
}
68
69
const
QString
&
QQmlPropertyMapPrivate
::
propertyName
(
int
index)
const
70
{
71
Q_ASSERT(index < keys.size());
72
return
keys[index];
73
}
74
75
QQmlPropertyMapMetaObject
::
QQmlPropertyMapMetaObject
(QQmlPropertyMap *obj,
QQmlPropertyMapPrivate
*objPriv,
const
QMetaObject *staticMetaObject)
76
:
QQmlOpenMetaObject
(
obj
,
staticMetaObject
)
77
{
78
map = obj;
79
priv = objPriv;
80
}
81
82
QVariant
QQmlPropertyMapMetaObject
::
propertyWriteValue
(
int
index,
const
QVariant &input)
83
{
84
return
priv->updateValue(priv->propertyName(index), input);
85
}
86
87
void
QQmlPropertyMapMetaObject
::
propertyWritten
(
int
index)
88
{
89
priv->emitChanged(priv->propertyName(index), value(index));
90
}
91
92
void
QQmlPropertyMapMetaObject
::
propertyCreated
(
int
, QMetaPropertyBuilder &b)
93
{
94
priv->keys.append(QString::fromUtf8(b.name()));
95
}
96
97
/*!
98
\class QQmlPropertyMap
99
\brief The QQmlPropertyMap class allows you to set key-value pairs that can be used in QML bindings.
100
\inmodule QtQml
101
102
QQmlPropertyMap provides a convenient way to expose domain data to the UI layer.
103
The following example shows how you might declare data in C++ and then
104
access it in QML.
105
106
In the C++ file:
107
\code
108
// create our data
109
QQmlPropertyMap ownerData;
110
ownerData.insert("name", QVariant(QString("John Smith")));
111
ownerData.insert("phone", QVariant(QString("555-5555")));
112
113
// expose it to the UI layer
114
QQuickView view;
115
QQmlContext *ctxt = view.rootContext();
116
ctxt->setContextProperty("owner", &ownerData);
117
118
view.setSource(QUrl::fromLocalFile("main.qml"));
119
view.show();
120
\endcode
121
122
Then, in \c main.qml:
123
\code
124
Text { text: owner.name + " " + owner.phone }
125
\endcode
126
127
The binding is dynamic - whenever a key's value is updated, anything bound to that
128
key will be updated as well.
129
130
To detect value changes made in the UI layer you can connect to the valueChanged() signal.
131
However, note that valueChanged() is \b NOT emitted when changes are made by calling insert()
132
or clear() - it is only emitted when a value is updated from QML.
133
134
\note It is not possible to remove keys from the map; once a key has been added, you can only
135
modify or clear its associated value.
136
137
\note When deriving a class from QQmlPropertyMap, use the
138
\l {QQmlPropertyMap::QQmlPropertyMap(DerivedType *derived, QObject *parent)} {protected two-argument constructor}
139
which ensures that the class is correctly registered with the Qt \l {Meta-Object System}.
140
141
\note The QMetaObject of a QQmlPropertyMap is dynamically generated and modified.
142
Operations on that meta object are not thread safe, so applications need to take
143
care to explicitly synchronize access to the meta object.
144
*/
145
146
#
if
QT_DEPRECATED_SINCE
(
6
,
11
)
147
/*!
148
\deprecated [6.11] Use the factory or the protected two-argument constructor instead.
149
150
Constructs a bindable map with parent object \a parent.
151
*/
152
QQmlPropertyMap::QQmlPropertyMap(QObject *parent)
153
: QQmlPropertyMap(&staticMetaObject, parent)
154
{
155
}
156
#
endif
// QT_DEPRECATED_SINCE(6, 11)
157
158
/*!
159
Creates a bindable map with parent object \a parent.
160
*/
161
QQmlPropertyMap *QQmlPropertyMap::create(QObject *parent)
162
{
163
return
new
QQmlPropertyMap(&staticMetaObject, parent);
164
}
165
166
/*!
167
Destroys the bindable map.
168
*/
169
QQmlPropertyMap::~QQmlPropertyMap()
170
{
171
}
172
173
/*!
174
Clears the value (if any) associated with \a key.
175
*/
176
void
QQmlPropertyMap::clear(
const
QString &key)
177
{
178
Q_D(QQmlPropertyMap);
179
if
(d->validKeyName(key))
180
d->mo->setValue(key.toUtf8(), QVariant());
181
}
182
183
/*!
184
\since 6.1
185
186
Disallows any further properties to be added to this property map.
187
Existing properties can be modified or cleared.
188
189
In turn, an internal cache is turned on for the existing properties, which
190
may result in faster access from QML.
191
*/
192
void
QQmlPropertyMap::freeze()
193
{
194
Q_D(QQmlPropertyMap);
195
d->mo->setAutoCreatesProperties(
false
);
196
d->mo->setCached(
true
);
197
}
198
199
/*!
200
Returns the value associated with \a key.
201
202
If no value has been set for this key (or if the value has been cleared),
203
an invalid QVariant is returned.
204
*/
205
QVariant QQmlPropertyMap::value(
const
QString &key)
const
206
{
207
Q_D(
const
QQmlPropertyMap);
208
return
d->mo->value(key.toUtf8());
209
}
210
211
/*!
212
Sets the value associated with \a key to \a value.
213
214
If the key doesn't exist, it is automatically created.
215
*/
216
void
QQmlPropertyMap::insert(
const
QString &key,
const
QVariant &value)
217
{
218
Q_D(QQmlPropertyMap);
219
220
if
(d->validKeyName(key)) {
221
d->mo->setValue(key.toUtf8(), value);
222
}
else
{
223
qWarning() <<
"Creating property with name"
224
<< key
225
<<
"is not permitted, conflicts with internal symbols."
;
226
}
227
}
228
229
/*!
230
\since 6.1
231
232
Inserts the \a values into the QQmlPropertyMap.
233
234
Keys that don't exist are automatically created.
235
236
This method is substantially faster than calling \c{insert(key, value)}
237
many times in a row.
238
*/
239
void
QQmlPropertyMap::insert(
const
QVariantHash &values)
240
{
241
Q_D(QQmlPropertyMap);
242
243
QHash<QByteArray, QVariant> checkedValues;
244
for
(
auto
it = values.begin(), end = values.end(); it != end; ++it) {
245
const
QString &key = it.key();
246
if
(!d->validKeyName(key)) {
247
qWarning() <<
"Creating property with name"
248
<< key
249
<<
"is not permitted, conflicts with internal symbols."
;
250
return
;
251
}
252
253
checkedValues.insert(key.toUtf8(), it.value());
254
}
255
d->mo->setValues(checkedValues);
256
257
}
258
259
/*!
260
Returns the list of keys.
261
262
Keys that have been cleared will still appear in this list, even though their
263
associated values are invalid QVariants.
264
*/
265
QStringList QQmlPropertyMap::keys()
const
266
{
267
Q_D(
const
QQmlPropertyMap);
268
return
d->keys;
269
}
270
271
/*!
272
\overload
273
274
Same as size().
275
*/
276
int
QQmlPropertyMap::count()
const
277
{
278
Q_D(
const
QQmlPropertyMap);
279
return
d->keys.size();
280
}
281
282
/*!
283
Returns the number of keys in the map.
284
285
\sa isEmpty(), count()
286
*/
287
int
QQmlPropertyMap::size()
const
288
{
289
Q_D(
const
QQmlPropertyMap);
290
return
d->keys.size();
291
}
292
293
/*!
294
Returns true if the map contains no keys; otherwise returns
295
false.
296
297
\sa size()
298
*/
299
bool
QQmlPropertyMap::isEmpty()
const
300
{
301
Q_D(
const
QQmlPropertyMap);
302
return
d->keys.isEmpty();
303
}
304
305
/*!
306
Returns true if the map contains \a key.
307
308
\sa size()
309
*/
310
bool
QQmlPropertyMap::contains(
const
QString &key)
const
311
{
312
Q_D(
const
QQmlPropertyMap);
313
return
d->keys.contains(key);
314
}
315
316
/*!
317
Returns the value associated with the key \a key as a modifiable
318
reference.
319
320
If the map contains no item with key \a key, the function inserts
321
an invalid QVariant into the map with key \a key, and
322
returns a reference to it.
323
324
\sa insert(), value()
325
*/
326
QVariant &QQmlPropertyMap::operator[](
const
QString &key)
327
{
328
//### optimize
329
Q_D(QQmlPropertyMap);
330
QByteArray utf8key = key.toUtf8();
331
if
(!d->keys.contains(key))
332
insert(key, QVariant());
//force creation -- needed below
333
334
return
d->mo->valueRef(utf8key);
335
}
336
337
/*!
338
\overload
339
340
Same as value().
341
*/
342
QVariant QQmlPropertyMap::operator[](
const
QString &key)
const
343
{
344
return
value(key);
345
}
346
347
/*!
348
Returns the new value to be stored for the key \a key. This function is provided
349
to intercept updates to a property from QML, where the value provided from QML is \a input.
350
351
Override this function to manipulate the property value as it is updated. Note that
352
this function is only invoked when the value is updated from QML.
353
*/
354
QVariant QQmlPropertyMap::updateValue(
const
QString &key,
const
QVariant &input)
355
{
356
Q_UNUSED(key);
357
return
input;
358
}
359
360
/*! \internal */
361
QQmlPropertyMap::QQmlPropertyMap(
const
QMetaObject *staticMetaObject, QObject *parent)
362
: QObject(*(
new
QQmlPropertyMapPrivate), parent)
363
{
364
Q_D(QQmlPropertyMap);
365
d->mo =
new
QQmlPropertyMapMetaObject(
this
, d, staticMetaObject);
366
}
367
368
/*!
369
\fn void QQmlPropertyMap::valueChanged(const QString &key, const QVariant &value)
370
This signal is emitted whenever one of the values in the map is changed. \a key
371
is the key corresponding to the \a value that was changed.
372
373
\note valueChanged() is \b NOT emitted when changes are made by calling insert()
374
or clear() - it is only emitted when a value is updated from QML.
375
*/
376
377
/*!
378
\fn template<class DerivedType> QQmlPropertyMap::QQmlPropertyMap(DerivedType *derived, QObject *parent)
379
380
Constructs a bindable map with parent object \a parent. Use this constructor
381
in classes derived from QQmlPropertyMap.
382
383
The type of \a derived is used to register the property map with the \l {Meta-Object System},
384
which is necessary to ensure that properties of the derived class are accessible.
385
This type must be derived from QQmlPropertyMap.
386
387
In the C++ file:
388
\snippet code/src_qml_qqmlpropertymap.cpp 0
389
390
\snippet code/src_qml_qqmlpropertymap.cpp 1
391
392
Then, in \c main.qml:
393
\code
394
MyQmlPropertyMap
395
{
396
id : owner
397
Component.onCompleted: { owner.updateEmail("new.email@example.com") }
398
}
399
Text { text : owner.name + " " + owner.phone + " " + owner.email }
400
\endcode
401
*/
402
403
QT_END_NAMESPACE
404
405
#
include
"moc_qqmlpropertymap.cpp"
QQmlPropertyMapMetaObject
Definition
qqmlpropertymap.cpp:17
QQmlPropertyMapMetaObject::propertyName
const QString & propertyName(int index)
QQmlPropertyMapMetaObject::propertyWritten
void propertyWritten(int index) override
Definition
qqmlpropertymap.cpp:87
QQmlPropertyMapMetaObject::propertyWriteValue
QVariant propertyWriteValue(int, const QVariant &) override
Definition
qqmlpropertymap.cpp:82
QQmlPropertyMapMetaObject::propertyCreated
void propertyCreated(int, QMetaPropertyBuilder &) override
Definition
qqmlpropertymap.cpp:92
QQmlPropertyMapMetaObject::QQmlPropertyMapMetaObject
QQmlPropertyMapMetaObject(QQmlPropertyMap *obj, QQmlPropertyMapPrivate *objPriv, const QMetaObject *staticMetaObject)
Definition
qqmlpropertymap.cpp:75
QQmlPropertyMapPrivate
Definition
qqmlpropertymap.cpp:34
QQmlPropertyMapPrivate::updateValue
QVariant updateValue(const QString &key, const QVariant &input)
Definition
qqmlpropertymap.cpp:57
QQmlPropertyMapPrivate::emitChanged
void emitChanged(const QString &key, const QVariant &value)
Definition
qqmlpropertymap.cpp:63
QQmlPropertyMapPrivate::propertyName
const QString & propertyName(int index) const
Definition
qqmlpropertymap.cpp:69
QQmlPropertyMapPrivate::keys
QStringList keys
Definition
qqmlpropertymap.cpp:38
QQmlPropertyMapPrivate::validKeyName
static bool validKeyName(const QString &name)
Definition
qqmlpropertymap.cpp:47
QT_BEGIN_NAMESPACE
Combined button and popup list for selecting options.
Definition
qsequentialanimationgroup.cpp:47
qtdeclarative
src
qml
util
qqmlpropertymap.cpp
Generated on
for Qt by
1.18.0