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
qqmldelegatecomponent.cpp
Go to the documentation of this file.
1
// Copyright (C) 2018 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
"qqmldelegatecomponent_p.h"
6
#
include
<
QtQmlModels
/
private
/
qqmladaptormodel_p
.
h
>
7
8
QT_BEGIN_NAMESPACE
9
10
/*!
11
\qmltype DelegateChoice
12
\nativetype QQmlDelegateChoice
13
\inqmlmodule QtQml.Models
14
\since 6.9
15
\brief Encapsulates a delegate and when to use it.
16
17
The DelegateChoice type wraps a delegate and defines the circumstances
18
in which it should be chosen.
19
20
DelegateChoices can be nested inside a DelegateChooser.
21
22
\sa DelegateChooser
23
*/
24
25
/*!
26
\qmlproperty variant QtQml.Models::DelegateChoice::roleValue
27
This property holds the value used to match the role data for the role provided by \l DelegateChooser::role.
28
*/
29
QVariant QQmlDelegateChoice::roleValue()
const
30
{
31
return
m_value;
32
}
33
34
void
QQmlDelegateChoice::setRoleValue(
const
QVariant &value)
35
{
36
if
(m_value == value)
37
return
;
38
m_value = value;
39
emit roleValueChanged();
40
emit changed();
41
}
42
43
/*!
44
\qmlproperty int QtQml.Models::DelegateChoice::row
45
This property holds the value used to match the row value of model elements.
46
With models that have only the index property (and thus only one column), this property
47
should be intended as an index, and set to the desired index value.
48
49
\note Setting both row and index has undefined behavior. The two are equivalent and only
50
one should be used.
51
52
\sa index
53
*/
54
55
/*!
56
\qmlproperty int QtQml.Models::DelegateChoice::index
57
This property holds the value used to match the index value of model elements.
58
This is effectively an alias for \l row.
59
60
\sa row
61
*/
62
int
QQmlDelegateChoice::row()
const
63
{
64
return
m_row;
65
}
66
67
void
QQmlDelegateChoice::setRow(
int
r)
68
{
69
if
(m_row == r)
70
return
;
71
m_row = r;
72
emit rowChanged();
73
emit indexChanged();
74
emit changed();
75
}
76
77
/*!
78
\qmlproperty int QtQml.Models::DelegateChoice::column
79
This property holds the value used to match the column value of model elements.
80
*/
81
int
QQmlDelegateChoice::column()
const
82
{
83
return
m_column;
84
}
85
86
void
QQmlDelegateChoice::setColumn(
int
c)
87
{
88
if
(m_column == c)
89
return
;
90
m_column = c;
91
emit columnChanged();
92
emit changed();
93
}
94
95
QQmlComponent *QQmlDelegateChoice::delegate()
const
96
{
97
return
m_delegate;
98
}
99
100
/*!
101
\qmlproperty Component QtQml.Models::DelegateChoice::delegate
102
This property holds the delegate to use if this choice matches the model item.
103
*/
104
void
QQmlDelegateChoice::setDelegate(QQmlComponent *delegate)
105
{
106
if
(m_delegate == delegate)
107
return
;
108
QQmlAbstractDelegateComponent *adc =
static_cast
<QQmlAbstractDelegateComponent *>(m_delegate);
109
if
(adc)
110
disconnect(adc, &QQmlAbstractDelegateComponent::delegateChanged,
this
, &QQmlDelegateChoice::delegateChanged);
111
m_delegate = delegate;
112
adc =
static_cast
<QQmlAbstractDelegateComponent *>(delegate);
113
if
(adc)
114
connect(adc, &QQmlAbstractDelegateComponent::delegateChanged,
this
, &QQmlDelegateChoice::delegateChanged);
115
emit delegateChanged();
116
emit changed();
117
}
118
119
bool
QQmlDelegateChoice::match(
int
row,
int
column,
const
QVariant &value)
const
120
{
121
if
(!m_value.isValid() && m_row < 0 && m_column < 0)
122
return
true
;
123
124
bool
roleMatched =
true
;
125
if
(m_value.isValid()) {
126
roleMatched = (value == m_value);
127
if
(!roleMatched) {
128
bool
valueOk =
false
;
129
bool
mValueOk =
false
;
130
roleMatched = (value.toInt(&valueOk) == m_value.toInt(&mValueOk) && valueOk && mValueOk);
131
}
132
if
(!roleMatched)
133
roleMatched = (value.toString() == m_value.toString());
134
}
135
const
bool
rowMatched = (m_row < 0 ) ?
true
: m_row == row;
136
const
bool
columnMatched = (m_column < 0 ) ?
true
: m_column == column;
137
return
roleMatched && rowMatched && columnMatched;
138
}
139
140
/*!
141
\qmltype DelegateChooser
142
\nativetype QQmlDelegateChooser
143
\inqmlmodule QtQml.Models
144
\since 6.9
145
\brief Allows a view to use different delegates for different types of items in the model.
146
147
The DelegateChooser is a special \l Component type intended for those scenarios where a
148
Component is required by a view and used as a delegate. DelegateChooser encapsulates a set of \l
149
{DelegateChoice}s. These choices are used to determine the delegate that will be instantiated for
150
each item in the model. The selection of the choice is performed based on the value that a model
151
item has for \l role, and also based on index.
152
153
DelegateChooser is commonly used when a view needs to display a set of delegates that are
154
significantly different from each other. For example, a typical phone settings view might include
155
toggle switches, sliders, radio buttons, and other visualizations based on the type of each
156
setting. In this case, DelegateChooser could provide an easy way to associate a different type of
157
delegate with each setting:
158
159
\qml
160
import QtQml.Models
161
import QtQuick
162
import QtQuick.Controls
163
164
ListView {
165
width: 200; height: 400
166
167
ListModel {
168
id: listModel
169
ListElement { type: "info"; ... }
170
ListElement { type: "switch"; ... }
171
ListElement { type: "swipe"; ... }
172
ListElement { type: "switch"; ... }
173
}
174
175
DelegateChooser {
176
id: chooser
177
role: "type"
178
DelegateChoice { roleValue: "info"; ItemDelegate { ... } }
179
DelegateChoice { roleValue: "switch"; SwitchDelegate { ... } }
180
DelegateChoice { roleValue: "swipe"; SwipeDelegate { ... } }
181
}
182
183
model: listModel
184
delegate: chooser
185
}
186
\endqml
187
188
\note This type is intended to transparently work only with TableView and any
189
DelegateModel-based view. Views (including user-defined views) that aren't internally based on a
190
DelegateModel need to explicitly support this type of component to make it function as described.
191
192
\sa DelegateChoice
193
*/
194
195
/*!
196
\qmlproperty string QtQml.Models::DelegateChooser::role
197
This property holds the role or the property name used to determine the delegate for a given model item.
198
199
\note For \l{QAbstractItemModel} based models, including \l{ListModel}, the DelegateChooser will
200
reevaluate the choice when the model signals that the role has changed. For any other type of model,
201
this choice will only be done once when the item for a given model index is created.
202
203
\sa DelegateChoice
204
*/
205
void
QQmlDelegateChooser::setRole(
const
QString &role)
206
{
207
if
(m_role == role)
208
return
;
209
m_role = role;
210
emit roleChanged();
211
}
212
213
/*!
214
\qmlproperty list<DelegateChoice> QtQml.Models::DelegateChooser::choices
215
\qmldefault
216
217
The list of DelegateChoices for the chooser.
218
219
The list is treated as an ordered list, where the first DelegateChoice to match
220
will be used be a view.
221
222
It should not generally be necessary to refer to the \c choices property,
223
as it is the default property for DelegateChooser and thus all child items are
224
automatically assigned to this property.
225
*/
226
227
QQmlListProperty<QQmlDelegateChoice> QQmlDelegateChooser::choices()
228
{
229
return
QQmlListProperty<QQmlDelegateChoice>(
this
,
nullptr
,
230
QQmlDelegateChooser::choices_append,
231
QQmlDelegateChooser::choices_count,
232
QQmlDelegateChooser::choices_at,
233
QQmlDelegateChooser::choices_clear,
234
QQmlDelegateChooser::choices_replace,
235
QQmlDelegateChooser::choices_removeLast);
236
}
237
238
void
QQmlDelegateChooser::choices_append(QQmlListProperty<QQmlDelegateChoice> *prop, QQmlDelegateChoice *choice)
239
{
240
QQmlDelegateChooser *q =
static_cast
<QQmlDelegateChooser *>(prop->object);
241
q->m_choices.append(choice);
242
connect(choice, &QQmlDelegateChoice::changed, q, &QQmlAbstractDelegateComponent::delegateChanged);
243
emit q->delegateChanged();
244
}
245
246
qsizetype QQmlDelegateChooser::choices_count(QQmlListProperty<QQmlDelegateChoice> *prop)
247
{
248
QQmlDelegateChooser *q =
static_cast
<QQmlDelegateChooser*>(prop->object);
249
return
q->m_choices.size();
250
}
251
252
QQmlDelegateChoice *QQmlDelegateChooser::choices_at(QQmlListProperty<QQmlDelegateChoice> *prop, qsizetype index)
253
{
254
QQmlDelegateChooser *q =
static_cast
<QQmlDelegateChooser*>(prop->object);
255
return
q->m_choices.at(index);
256
}
257
258
void
QQmlDelegateChooser::choices_clear(QQmlListProperty<QQmlDelegateChoice> *prop)
259
{
260
QQmlDelegateChooser *q =
static_cast
<QQmlDelegateChooser *>(prop->object);
261
for
(QQmlDelegateChoice *choice : q->m_choices)
262
disconnect(choice, &QQmlDelegateChoice::changed, q, &QQmlAbstractDelegateComponent::delegateChanged);
263
q->m_choices.clear();
264
emit q->delegateChanged();
265
}
266
267
void
QQmlDelegateChooser::choices_replace(QQmlListProperty<QQmlDelegateChoice> *prop,
268
qsizetype index, QQmlDelegateChoice *choice)
269
{
270
QQmlDelegateChooser *q =
static_cast
<QQmlDelegateChooser *>(prop->object);
271
disconnect(q->m_choices[index], &QQmlDelegateChoice::changed,
272
q, &QQmlAbstractDelegateComponent::delegateChanged);
273
q->m_choices[index] = choice;
274
connect(choice, &QQmlDelegateChoice::changed, q,
275
&QQmlAbstractDelegateComponent::delegateChanged);
276
emit q->delegateChanged();
277
}
278
279
void
QQmlDelegateChooser::choices_removeLast(QQmlListProperty<QQmlDelegateChoice> *prop)
280
{
281
QQmlDelegateChooser *q =
static_cast
<QQmlDelegateChooser *>(prop->object);
282
disconnect(q->m_choices.takeLast(), &QQmlDelegateChoice::changed,
283
q, &QQmlAbstractDelegateComponent::delegateChanged);
284
emit q->delegateChanged();
285
}
286
287
QQmlComponent *QQmlDelegateChooser::delegate(QQmlAdaptorModel *adaptorModel,
int
row,
int
column)
const
288
{
289
QVariant v;
290
if
(!m_role.isNull())
291
v = value(adaptorModel, row, column, m_role);
292
if
(!v.isValid()) {
// check if the row only has modelData, for example if the row is a QVariantMap
293
v = value(adaptorModel, row, column, QStringLiteral(
"modelData"
));
294
295
if
(v.isValid()) {
296
if
(v.canConvert(QMetaType(QMetaType::QVariantMap)))
297
v = v.toMap().value(m_role);
298
else
if
(v.canConvert(QMetaType(QMetaType::QObjectStar)))
299
v = v.value<QObject*>()->property(m_role.toUtf8());
300
}
301
}
302
303
// loop through choices, finding first one that fits
304
for
(
int
i = 0; i < m_choices.size(); ++i) {
305
const
QQmlDelegateChoice *choice = m_choices.at(i);
306
if
(choice->match(row, column, v))
307
return
choice->delegate();
308
}
309
310
return
nullptr
;
311
}
312
313
QT_END_NAMESPACE
314
315
#
include
"moc_qqmldelegatecomponent_p.cpp"
QT_BEGIN_NAMESPACE
Combined button and popup list for selecting options.
Definition
qsequentialanimationgroup.cpp:47
qtdeclarative
src
qmlmodels
qqmldelegatecomponent.cpp
Generated on
for Qt by
1.18.0