Qt
Internal/Contributor docs for the Qt SDK. <b>Note:</b> These are NOT official API docs; those are found <a href='https://doc.qt.io/'>here</a>.
Loading...
Searching...
No Matches
qqmltableinstancemodel.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
6
7#include <QtCore/QTimer>
8
9#include <QtQml/private/qqmlincubator_p.h>
10#include <QtQmlModels/private/qqmlchangeset_p.h>
11#include <QtQml/private/qqmlcomponent_p.h>
12
14
15const char* kModelItemTag = "_tableinstancemodel_modelItem";
16
17bool QQmlTableInstanceModel::isDoneIncubating(QQmlDelegateModelItem *modelItem)
18{
19 if (!modelItem->incubationTask)
20 return true;
21
22 const auto status = modelItem->incubationTask->status();
23 return (status == QQmlIncubator::Ready) || (status == QQmlIncubator::Error);
24}
25
26void QQmlTableInstanceModel::deleteModelItemLater(QQmlDelegateModelItem *modelItem)
27{
28 Q_ASSERT(modelItem);
29
30 delete modelItem->object;
31 modelItem->object = nullptr;
32 modelItem->contextData.reset();
33 modelItem->deleteLater();
34}
35
43
45{
46 m_adaptorModel.useImportVersion(version);
47}
48
50{
51 for (const auto modelItem : m_modelItems) {
52 // No item in m_modelItems should be referenced at this point. The view
53 // should release all its items before it deletes this model. Only model items
54 // that are still being incubated should be left for us to delete.
55 Q_ASSERT(modelItem->objectRef == 0);
56 Q_ASSERT(modelItem->incubationTask);
57 // Check that we are not being deleted while we're
58 // in the process of e.g emitting a created signal.
59 Q_ASSERT(modelItem->scriptRef == 0);
60
61 if (modelItem->object) {
62 delete modelItem->object;
63 modelItem->object = nullptr;
64 modelItem->contextData.reset();
65 }
66 }
67
68 deleteAllFinishedIncubationTasks();
69 qDeleteAll(m_modelItems);
71}
72
73QQmlComponent *QQmlTableInstanceModel::resolveDelegate(int index)
74{
75 if (m_delegateChooser) {
76 const int row = m_adaptorModel.rowAt(index);
77 const int column = m_adaptorModel.columnAt(index);
78 QQmlComponent *delegate = nullptr;
79 QQmlAbstractDelegateComponent *chooser = m_delegateChooser;
80 do {
81 delegate = chooser->delegate(&m_adaptorModel, row, column);
82 chooser = qobject_cast<QQmlAbstractDelegateComponent *>(delegate);
83 } while (chooser);
84 return delegate;
85 }
86
87 return m_delegate;
88}
89
90QQmlDelegateModelItem *QQmlTableInstanceModel::resolveModelItem(int index)
91{
92 // Check if an item for the given index is already loaded and ready
93 QQmlDelegateModelItem *modelItem = m_modelItems.value(index, nullptr);
94 if (modelItem)
95 return modelItem;
96
97 QQmlComponent *delegate = resolveDelegate(index);
98 if (!delegate)
99 return nullptr;
100
101 // Check if the pool contains an item that can be reused
102 modelItem = m_reusableItemsPool.takeItem(delegate, index);
103 if (modelItem) {
104 reuseItem(modelItem, index);
105 m_modelItems.insert(index, modelItem);
106 return modelItem;
107 }
108
109 // Create a new item from scratch
110 modelItem = m_adaptorModel.createItem(m_metaType.data(), index);
111 if (modelItem) {
112 modelItem->delegate = delegate;
113 m_modelItems.insert(index, modelItem);
114 return modelItem;
115 }
116
117 qWarning() << Q_FUNC_INFO << "failed creating a model item for index: " << index;
118 return nullptr;
119}
120
122{
123 Q_ASSERT(m_delegate);
124 Q_ASSERT(index >= 0 && index < m_adaptorModel.count());
125 Q_ASSERT(m_qmlContext && m_qmlContext->isValid());
126
127 QQmlDelegateModelItem *modelItem = resolveModelItem(index);
128 if (!modelItem)
129 return nullptr;
130
131 if (modelItem->object) {
132 // The model item has already been incubated. So
133 // just bump the ref-count and return it.
134 modelItem->referenceObject();
135 return modelItem->object;
136 }
137
138 // The object is not ready, and needs to be incubated
139 incubateModelItem(modelItem, incubationMode);
140 if (!isDoneIncubating(modelItem))
141 return nullptr;
142
143 // Incubation is done, so the task should be removed
144 Q_ASSERT(!modelItem->incubationTask);
145
146 if (!modelItem->object) {
147 // The object was incubated synchronously (otherwise we would return above). But since
148 // we have no object, the incubation must have failed. And when we have no object, there
149 // should be no object references either. And there should also not be any internal script
150 // refs at this point. So we delete the model item.
151 Q_ASSERT(!modelItem->isObjectReferenced());
152 Q_ASSERT(!modelItem->isReferenced());
153 m_modelItems.remove(modelItem->index);
154 delete modelItem;
155 return nullptr;
156 }
157
158 // Incubation was completed sync and successful
159 modelItem->referenceObject();
160 return modelItem->object;
161}
162
163QQmlInstanceModel::ReleaseFlags QQmlTableInstanceModel::release(QObject *object, ReusableFlag reusable)
164{
165 Q_ASSERT(object);
166 auto modelItem = qvariant_cast<QQmlDelegateModelItem *>(object->property(kModelItemTag));
167 Q_ASSERT(modelItem);
168 // Ensure that the object was incubated by this QQmlTableInstanceModel
169 Q_ASSERT(m_modelItems.contains(modelItem->index));
170 Q_ASSERT(m_modelItems[modelItem->index]->object == object);
171
172 if (!modelItem->releaseObject())
174
175 if (modelItem->isReferenced()) {
176 // We still have an internal reference to this object, which means that we are told to release an
177 // object while the createdItem signal for it is still on the stack. This can happen when objects
178 // are e.g delivered async, and the user flicks back and forth quicker than the loading can catch
179 // up with. The view might then find that the object is no longer visible and should be released.
180 // We detect this case in incubatorStatusChanged(), and delete it there instead. But from the callers
181 // point of view, it should consider it destroyed.
183 }
184
185 // The item is not referenced by anyone
186 m_modelItems.remove(modelItem->index);
187
188 if (reusable == Reusable) {
189 m_reusableItemsPool.insertItem(modelItem);
190 emit itemPooled(modelItem->index, modelItem->object);
192 }
193
194 // The item is not reused or referenced by anyone, so just delete it
195 destroyModelItem(modelItem, Deferred);
197}
198
199void QQmlTableInstanceModel::destroyModelItem(QQmlDelegateModelItem *modelItem, DestructionMode mode)
200{
201 emit destroyingItem(modelItem->object);
202 if (mode == Deferred)
203 modelItem->destroyObject();
204 else
205 delete modelItem->object;
206 delete modelItem;
207}
208
210{
211 Q_ASSERT(object);
212 auto modelItem = qvariant_cast<QQmlDelegateModelItem *>(object->property(kModelItemTag));
213 Q_ASSERT(modelItem);
214
215 modelItem->releaseObject();
216
217 // The item is not referenced by anyone
218 Q_ASSERT(!modelItem->isObjectReferenced());
219 Q_ASSERT(!modelItem->isReferenced());
220 // Ensure that the object was incubated by this QQmlTableInstanceModel
221 Q_ASSERT(m_modelItems.contains(modelItem->index));
222 Q_ASSERT(m_modelItems[modelItem->index]->object == object);
223
224 m_modelItems.remove(modelItem->index);
225
226 emit destroyingItem(object);
227 delete object;
228 delete modelItem;
229}
230
232{
233 auto modelItem = m_modelItems.value(index);
234 Q_ASSERT(modelItem);
235
236 // Since the view expects the item to be incubating, there should be
237 // an incubation task. And since the incubation is not done, no-one
238 // should yet have received, and therfore hold a reference to, the object.
239 Q_ASSERT(modelItem->incubationTask);
240 Q_ASSERT(!modelItem->isObjectReferenced());
241
242 m_modelItems.remove(index);
243
244 if (modelItem->object)
245 delete modelItem->object;
246
247 // modelItem->incubationTask will be deleted from the modelItems destructor
248 delete modelItem;
249}
250
252{
253 m_reusableItemsPool.drain(maxPoolTime, [this](QQmlDelegateModelItem *modelItem) {
254 destroyModelItem(modelItem, Immediate);
255 });
256}
257
259{
260 // Update the context properties index, row and column on
261 // the delegate item, and inform the application about it.
262 // Note that we set alwaysEmit to true, to force all bindings
263 // to be reevaluated, even if the index didn't change (since
264 // the model can have changed size since last usage).
265 const bool alwaysEmit = true;
266 const int newRow = m_adaptorModel.rowAt(newModelIndex);
267 const int newColumn = m_adaptorModel.columnAt(newModelIndex);
268 item->setModelIndex(newModelIndex, newRow, newColumn, alwaysEmit);
269
270 // Notify the application that all 'dynamic'/role-based context data has
271 // changed as well (their getter function will use the updated index).
272 auto const itemAsList = QList<QQmlDelegateModelItem *>() << item;
273 auto const updateAllRoles = QVector<int>();
274 m_adaptorModel.notify(itemAsList, newModelIndex, 1, updateAllRoles);
275
276 // Inform the view that the item is recycled. This will typically result
277 // in the view updating its own attached delegate item properties.
278 emit itemReused(newModelIndex, item->object);
279}
280
281void QQmlTableInstanceModel::incubateModelItem(QQmlDelegateModelItem *modelItem, QQmlIncubator::IncubationMode incubationMode)
282{
283 // Guard the model item temporarily so that it's not deleted from
284 // incubatorStatusChanged(), in case the incubation is done synchronously.
285 modelItem->scriptRef++;
286
287 if (modelItem->incubationTask) {
288 // We're already incubating the model item from a previous request. If the previous call requested
289 // the item async, but the current request needs it sync, we need to force-complete the incubation.
290 const bool sync = (incubationMode == QQmlIncubator::Synchronous || incubationMode == QQmlIncubator::AsynchronousIfNested);
291 if (sync && modelItem->incubationTask->incubationMode() == QQmlIncubator::Asynchronous)
292 modelItem->incubationTask->forceCompletion();
293 } else {
294 modelItem->incubationTask = new QQmlTableInstanceModelIncubationTask(this, modelItem, incubationMode);
295
296 QQmlContext *creationContext = modelItem->delegate->creationContext();
297 const QQmlRefPointer<QQmlContextData> componentContext
298 = QQmlContextData::get(creationContext ? creationContext : m_qmlContext.data());
299
300 QQmlComponentPrivate *cp = QQmlComponentPrivate::get(modelItem->delegate);
301 if (cp->isBound()) {
302 modelItem->contextData = componentContext;
303 cp->incubateObject(
304 modelItem->incubationTask,
305 modelItem->delegate,
306 m_qmlContext->engine(),
307 componentContext,
308 QQmlContextData::get(m_qmlContext));
309 } else {
310 QQmlRefPointer<QQmlContextData> ctxt = QQmlContextData::createRefCounted(
311 QQmlContextData::get(creationContext ? creationContext : m_qmlContext.data()));
312 ctxt->setContextObject(modelItem);
313 modelItem->contextData = ctxt;
314
315 cp->incubateObject(
316 modelItem->incubationTask,
317 modelItem->delegate,
318 m_qmlContext->engine(),
319 ctxt,
320 QQmlContextData::get(m_qmlContext));
321 }
322 }
323
324 // Remove the temporary guard
325 modelItem->scriptRef--;
326}
327
328void QQmlTableInstanceModel::incubatorStatusChanged(QQmlTableInstanceModelIncubationTask *incubationTask, QQmlIncubator::Status status)
329{
330 QQmlDelegateModelItem *modelItem = incubationTask->modelItemToIncubate;
331 Q_ASSERT(modelItem->incubationTask);
332
333 modelItem->incubationTask = nullptr;
334 incubationTask->modelItemToIncubate = nullptr;
335
336 if (status == QQmlIncubator::Ready) {
337 // Tag the incubated object with the model item for easy retrieval upon release etc.
338 modelItem->object->setProperty(kModelItemTag, QVariant::fromValue(modelItem));
339
340 // Emit that the item has been created. What normally happens next is that the view
341 // upon receiving the signal asks for the model item once more. And since the item is
342 // now in the map, it will be returned directly.
343 Q_ASSERT(modelItem->object);
344 modelItem->scriptRef++;
345 emit createdItem(modelItem->index, modelItem->object);
346 modelItem->scriptRef--;
347 } else if (status == QQmlIncubator::Error) {
348 qWarning() << "Error incubating delegate:" << incubationTask->errors();
349 }
350
351 if (!modelItem->isReferenced() && !modelItem->isObjectReferenced()) {
352 // We have no internal reference to the model item, and the view has no
353 // reference to the incubated object. So just delete the model item.
354 // Note that being here means that the object was incubated _async_
355 // (otherwise modelItem->isReferenced() would be true).
356 m_modelItems.remove(modelItem->index);
357
358 if (modelItem->object) {
359 modelItem->scriptRef++;
360 emit destroyingItem(modelItem->object);
361 modelItem->scriptRef--;
362 Q_ASSERT(!modelItem->isReferenced());
363 }
364
365 deleteModelItemLater(modelItem);
366 }
367
368 deleteIncubationTaskLater(incubationTask);
369}
370
372 const auto modelItem = m_modelItems.value(index, nullptr);
373 if (!modelItem)
374 return QQmlIncubator::Null;
375
376 if (modelItem->incubationTask)
377 return modelItem->incubationTask->status();
378
379 // Since we clear the incubation task when we're done
380 // incubating, it means that the status is Ready.
382}
383
385{
386 // This function can be called from the view upon
387 // receiving the initItem signal. It can be used to
388 // give all required delegate properties used by the
389 // view an initial value.
390 const auto modelItem = m_modelItems.value(index, nullptr);
391 if (!modelItem)
392 return false;
393 if (!modelItem->object)
394 return false;
395 if (!modelItem->incubationTask)
396 return false;
397
398 bool wasInRequired = false;
399 const auto task = QQmlIncubatorPrivate::get(modelItem->incubationTask);
400 RequiredProperties *props = task->requiredProperties();
401 if (props->empty())
402 return false;
403
405 modelItem->object, name, props, QQmlEnginePrivate::get(task->enginePriv),
406 &wasInRequired);
407 if (wasInRequired)
408 componentProp.write(value);
409 return wasInRequired;
410}
411
412void QQmlTableInstanceModel::deleteIncubationTaskLater(QQmlIncubator *incubationTask)
413{
414 // We often need to post-delete incubation tasks, since we cannot
415 // delete them while we're in the middle of an incubation change callback.
416 Q_ASSERT(!m_finishedIncubationTasks.contains(incubationTask));
417 m_finishedIncubationTasks.append(incubationTask);
418 if (m_finishedIncubationTasks.size() == 1)
419 QTimer::singleShot(1, this, &QQmlTableInstanceModel::deleteAllFinishedIncubationTasks);
420}
421
422void QQmlTableInstanceModel::deleteAllFinishedIncubationTasks()
423{
424 qDeleteAll(m_finishedIncubationTasks);
425 m_finishedIncubationTasks.clear();
426}
427
429{
430 return m_adaptorModel.model();
431}
432
434{
435 // Pooled items are still accessible/alive for the application, and
436 // needs to stay in sync with the model. So we need to drain the pool
437 // completely when the model changes.
439 if (auto const aim = abstractItemModel()) {
440 disconnect(aim, &QAbstractItemModel::dataChanged, this, &QQmlTableInstanceModel::dataChangedCallback);
441 disconnect(aim, &QAbstractItemModel::modelAboutToBeReset, this, &QQmlTableInstanceModel::modelAboutToBeResetCallback);
442 }
443 m_adaptorModel.setModel(model);
444 if (auto const aim = abstractItemModel()) {
445 connect(aim, &QAbstractItemModel::dataChanged, this, &QQmlTableInstanceModel::dataChangedCallback);
446 connect(aim, &QAbstractItemModel::modelAboutToBeReset, this, &QQmlTableInstanceModel::modelAboutToBeResetCallback);
447 }
448}
449
450void QQmlTableInstanceModel::dataChangedCallback(const QModelIndex &begin, const QModelIndex &end, const QVector<int> &roles)
451{
452 // This function is called when model data has changed. In that case, we tell the adaptor model
453 // to go through all the items we have created, find the ones that are affected, and notify that
454 // their model data has changed. This will in turn update QML bindings inside the delegate items.
455 int numberOfRowsChanged = end.row() - begin.row() + 1;
456 int numberOfColumnsChanged = end.column() - begin.column() + 1;
457
458 for (int column = 0; column < numberOfColumnsChanged; ++column) {
459 const int columnIndex = begin.column() + column;
460 const int rowIndex = begin.row() + (columnIndex * rows());
461 m_adaptorModel.notify(m_modelItems.values(), rowIndex, numberOfRowsChanged, roles);
462 }
463}
464
465void QQmlTableInstanceModel::modelAboutToBeResetCallback()
466{
467 // When the model is reset, we can no longer rely on any of the data it has
468 // provided us so far. Normally it's enough for the view to recreate all the
469 // delegate items in that case, except if the model roles has changed as well
470 // (since those are cached by QQmlAdaptorModel / Accessors). For the latter case, we
471 // simply set the model once more in the delegate model to rebuild everything.
472 auto const aim = abstractItemModel();
473 auto oldRoleNames = aim->roleNames();
474 QObject::connect(aim, &QAbstractItemModel::modelReset, this, [this, aim, oldRoleNames](){
475 if (oldRoleNames != aim->roleNames())
476 setModel(model());
478}
479
481{
482 return m_delegate;
483}
484
486{
487 if (m_delegate == delegate)
488 return;
489
490 m_delegateChooser = nullptr;
491 if (delegate) {
493 qobject_cast<QQmlAbstractDelegateComponent *>(delegate);
494 if (adc)
495 m_delegateChooser = adc;
496 }
497
498 m_delegate = delegate;
499}
500
502{
503 return m_adaptorModel.adaptsAim() ? m_adaptorModel.aim() : nullptr;
504}
505
506// --------------------------------------------------------
507
519
521{
522 if (!QQmlTableInstanceModel::isDoneIncubating(modelItemToIncubate))
523 return;
524
525 // We require the view to cancel any ongoing load
526 // requests before the tableInstanceModel is destructed.
528
529 tableInstanceModel->incubatorStatusChanged(this, status);
530}
531
533
534#include "moc_qqmltableinstancemodel_p.cpp"
535
void modelAboutToBeReset(QPrivateSignal)
void modelReset(QPrivateSignal)
void dataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight, const QList< int > &roles=QList< int >())
This signal is emitted whenever the data in an existing item changes.
bool remove(const Key &key)
Removes the item that has the key from the hash.
Definition qhash.h:958
QList< T > values() const
Returns a list containing all the values in the hash, in an arbitrary order.
Definition qhash.h:1098
bool contains(const Key &key) const noexcept
Returns true if the hash contains an item with the key; otherwise returns false.
Definition qhash.h:1007
T value(const Key &key) const noexcept
Definition qhash.h:1054
iterator insert(const Key &key, const T &value)
Inserts a new item with the key and a value of value.
Definition qhash.h:1303
qsizetype size() const noexcept
Definition qlist.h:397
void append(parameter_type t)
Definition qlist.h:458
void clear()
Definition qlist.h:434
\inmodule QtCore
\inmodule QtCore
Definition qobject.h:103
static QMetaObject::Connection connect(const QObject *sender, const char *signal, const QObject *receiver, const char *member, Qt::ConnectionType=Qt::AutoConnection)
\threadsafe
Definition qobject.cpp:2960
bool setProperty(const char *name, const QVariant &value)
Sets the value of the object's name property to value.
void deleteLater()
\threadsafe
Definition qobject.cpp:2435
void initializeRequiredProperties(QQmlDelegateModelItem *modelItemToIncubate, QObject *object)
bool notify(const QList< QQmlDelegateModelItem * > &items, int index, int count, const QVector< int > &roles) const
QAbstractItemModel * aim()
QVariant model() const
int rowAt(int index) const
QQmlDelegateModelItem * createItem(const QQmlRefPointer< QQmlDelegateModelItemMetaType > &metaType, int index)
int columnAt(int index) const
void useImportVersion(QTypeRevision revision)
void setModel(const QVariant &variant)
virtual void incubateObject(QQmlIncubator *incubationTask, QQmlComponent *component, QQmlEngine *engine, const QQmlRefPointer< QQmlContextData > &context, const QQmlRefPointer< QQmlContextData > &forContext)
static QQmlComponentPrivate * get(QQmlComponent *c)
static QQmlProperty removePropertyFromRequired(QObject *createdComponent, const QString &name, RequiredProperties *requiredProperties, QQmlEngine *engine, bool *wasInRequiredProperties=nullptr)
The QQmlComponent class encapsulates a QML component definition.
static QQmlRefPointer< QQmlContextData > get(QQmlContext *context)
static QQmlRefPointer< QQmlContextData > createRefCounted(const QQmlRefPointer< QQmlContextData > &parent)
The QQmlContext class defines a context within a QML engine.
Definition qqmlcontext.h:25
bool isValid() const
Returns whether the context is valid.
QQmlEngine * engine() const
Return the context's QQmlEngine, or \nullptr if the context has no QQmlEngine or the QQmlEngine was d...
QQDMIncubationTask * incubationTask
static QQmlEnginePrivate * get(QQmlEngine *e)
static QQmlIncubatorPrivate * get(QQmlIncubator *incubator)
The QQmlIncubator class allows QML objects to be created asynchronously.
QList< QQmlError > errors() const
Return the list of errors encountered while incubating the object.
QObject * object() const
Return the incubated object if the status is Ready, otherwise 0.
IncubationMode
Specifies the mode the incubator operates in.
Status status() const
Return the current status of the incubator.
Status
Specifies the status of the QQmlIncubator.
void createdItem(int index, QObject *object)
void destroyingItem(QObject *object)
void initItem(int index, QObject *object)
The QQmlProperty class abstracts accessing properties on objects created from QML.
T * data() const
void drain(int maxPoolTime, std::function< void(QQmlDelegateModelItem *cacheItem)> releaseItem)
void insertItem(QQmlDelegateModelItem *modelItem)
QQmlDelegateModelItem * takeItem(const QQmlComponent *delegate, int newIndexHint)
void statusChanged(Status status) override
Called when the status of the incubator changes.
void setInitialState(QObject *object) override
Called after the object is first created, but before complex property bindings are evaluated and,...
const QAbstractItemModel * abstractItemModel() const override
void drainReusableItemsPool(int maxPoolTime) override
bool setRequiredProperty(int index, const QString &name, const QVariant &value) final
QQmlTableInstanceModel(QQmlContext *qmlContext, QObject *parent=nullptr)
void reuseItem(QQmlDelegateModelItem *item, int newModelIndex)
void setModel(const QVariant &model)
QQmlComponent * delegate() const
void useImportVersion(QTypeRevision version)
friend class QQmlTableInstanceModelIncubationTask
void setDelegate(QQmlComponent *)
QQmlIncubator::Status incubationStatus(int index) override
ReleaseFlags release(QObject *object, ReusableFlag reusable=NotReusable) override
\inmodule QtCore
\macro QT_RESTRICTED_CAST_FROM_ASCII
Definition qstring.h:129
bool singleShot
whether the timer is a single-shot timer
Definition qtimer.h:22
\inmodule QtCore
\inmodule QtCore
Definition qvariant.h:65
static auto fromValue(T &&value) noexcept(std::is_nothrow_copy_constructible_v< T > &&Private::CanUseInternalSpace< T >) -> std::enable_if_t< std::conjunction_v< std::is_copy_constructible< T >, std::is_destructible< T > >, QVariant >
Definition qvariant.h:536
qDeleteAll(list.begin(), list.end())
Combined button and popup list for selecting options.
@ SingleShotConnection
#define Q_FUNC_INFO
EGLOutputLayerEXT EGLint EGLAttrib value
[5]
#define qWarning
Definition qlogging.h:166
GLuint64 GLenum void * handle
GLenum mode
GLuint index
[2]
GLuint GLuint end
GLuint object
[3]
GLint GLsizei GLsizei GLenum GLenum GLsizei void * data
GLenum GLuint GLsizei const GLenum * props
GLuint name
GLenum GLenum GLsizei void GLsizei void * column
GLenum GLenum GLsizei void * row
QQmlContext * qmlContext(const QObject *obj)
Definition qqml.cpp:75
QT_BEGIN_NAMESPACE const char * kModelItemTag
#define Q_ASSERT(cond)
Definition qrandom.cpp:47
QtPrivate::QRegularExpressionMatchIteratorRangeBasedForIterator begin(const QRegularExpressionMatchIterator &iterator)
#define emit
QSqlQueryModel * model
[16]
QObject::connect nullptr
myObject disconnect()
[26]
QGraphicsItem * item
QJSEngine engine
[0]
bool contains(const AT &t) const noexcept
Definition qlist.h:45