7#include <QtQml/qqmlinfo.h>
8#include <QtQml/qqmlcomponent.h>
10#include <private/qqmlengine_p.h>
11#include <private/qqmlglobal_p.h>
13#include <private/qqmlcomponent_p.h>
14#include <private/qqmlincubator_p.h>
19 = QQuickItemPrivate::Geometry | QQuickItemPrivate::ImplicitWidth | QQuickItemPrivate::ImplicitHeight;
36 const QRectF &oldGeometry)
38 if (resizeItem ==
item)
40 QQuickItemChangeListener::itemGeometryChanged(resizeItem, change, oldGeometry);
46 q->setImplicitWidth(getImplicitWidth());
52 q->setImplicitHeight(getImplicitHeight());
68 QQmlContext *context = qmlContext(object);
70 QQmlContextData::get(context)->clearContextRecursively();
72 if (loadingFromSource && component) {
74 QObject::disconnect(component, SIGNAL(statusChanged(QQmlComponent::Status)),
75 q, SLOT(_q_sourceLoaded()));
76 QObject::disconnect(component, SIGNAL(progressChanged(qreal)),
77 q, SIGNAL(progressChanged()));
78 component->deleteLater();
79 component.setObject(
nullptr, q);
80 }
else if (component) {
81 component.setObject(
nullptr, q);
86 QQuickItemPrivate *p = QQuickItemPrivate::get(item);
87 p->removeItemChangeListener(
this, watchedChanges);
91 item->setParentItem(
nullptr);
92 item->setVisible(
false);
96 object->deleteLater();
105 QQuickItemPrivate *p = QQuickItemPrivate::get(item);
106 p->addItemChangeListener(
this, watchedChanges);
112 Q_Q(
const QQuickLoader);
117 return q->widthValid() ? item->implicitWidth() : item->width();
118 return QQuickImplicitSizeItemPrivate::getImplicitWidth();
123 Q_Q(
const QQuickLoader);
128 return q->heightValid() ? item->implicitHeight() : item->height();
129 return QQuickImplicitSizeItemPrivate::getImplicitHeight();
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
271QQuickLoader::QQuickLoader(QQuickItem *parent)
272 : QQuickImplicitSizeItem(*(
new QQuickLoaderPrivate), parent)
274 setFlag(ItemIsFocusScope);
277QQuickLoader::~QQuickLoader()
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298bool QQuickLoader::active()
const
300 Q_D(
const QQuickLoader);
304void QQuickLoader::setActive(
bool newVal)
307 if (d->active == newVal)
311 if (newVal ==
true) {
312 if (d->loadingFromSource) {
315 loadFromSourceComponent();
320 d->incubator->clear();
321 delete d->itemContext;
322 d->itemContext =
nullptr;
327 QQmlContext *context = qmlContext(d->object);
329 QQmlContextData::get(context)->clearContextRecursively();
332 QQuickItemPrivate *p = QQuickItemPrivate::get(d->item);
333 p->removeItemChangeListener(d, watchedChanges);
337 d->item->setParentItem(
nullptr);
338 d->item->setVisible(
false);
342 d->object->deleteLater();
348 emit activeChanged();
353
354
355
356
357
358
359
360
361
362
363
364
365QUrl QQuickLoader::source()
const
367 Q_D(
const QQuickLoader);
371void QQuickLoader::setSourceWithoutResolve(
const QUrl &url)
373 setSource(url,
true);
376void QQuickLoader::setSource(
const QUrl &url,
bool needsClear)
379 if (d->source == url)
386 d->loadingFromSource =
true;
391 emit sourceChanged();
394void QQuickLoader::loadFromSource()
397 if (d->source.isEmpty()) {
398 emit sourceChanged();
400 emit progressChanged();
405 if (isComponentComplete()) {
407 d->createComponent();
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
436QQmlComponent *QQuickLoader::sourceComponent()
const
438 Q_D(
const QQuickLoader);
442void QQuickLoader::setSourceComponent(QQmlComponent *comp)
445 if (comp == d->component)
450 d->component.setObject(comp,
this);
451 d->loadingFromSource =
false;
454 loadFromSourceComponent();
456 emit sourceComponentChanged();
459void QQuickLoader::resetSourceComponent()
461 setSourceComponent(
nullptr);
464void QQuickLoader::loadFromSourceComponent()
468 emit sourceComponentChanged();
470 emit progressChanged();
475 if (isComponentComplete())
480QUrl QQuickLoader::setSourceUrlHelper(
const QUrl &unresolvedUrl)
487 QUrl oldUrl = d->source;
489 QUrl sourceUrl = qmlEngine(
this)->handle()->callingQmlContext()->resolvedUrl(unresolvedUrl);
490 if (!sourceUrl.isValid())
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559void QQuickLoader::setSource(
const QUrl &source, QJSValue properties)
563 if (!(properties.isArray() || properties.isObject())) {
564 qmlWarning(
this) << QQuickLoader::tr(
"setSource: value is not an object");
568 QUrl sourceUrl = setSourceUrlHelper(source);
570 d->disposeInitialPropertyValues();
571 auto engine = qmlEngine(
this)->handle();
572 d->initialPropertyValues.set(engine, QJSValuePrivate::takeManagedValue(&properties)->asReturnedValue());
573 d->qmlCallingContext.set(engine, engine->qmlContext());
575 setSource(sourceUrl,
false);
578void QQuickLoader::setSource(
const QUrl &source)
582 QUrl sourceUrl = setSourceUrlHelper(source);
584 d->disposeInitialPropertyValues();
585 auto engine = qmlEngine(
this)->handle();
586 d->qmlCallingContext.set(engine, engine->qmlContext());
588 setSource(sourceUrl,
false);
593 initialPropertyValues.clear();
600 if (!q->isComponentComplete() || !component)
603 if (!component->isLoading()) {
606 QObject::connect(component, SIGNAL(statusChanged(QQmlComponent::Status)),
607 q, SLOT(_q_sourceLoaded()));
608 QObject::connect(component, SIGNAL(progressChanged(qreal)),
609 q, SIGNAL(progressChanged()));
611 emit q->progressChanged();
613 emit q->sourceChanged();
615 emit q->sourceComponentChanged();
616 emit q->itemChanged();
622 loader->setInitialState(o);
629 QQuickItem *item = qmlobject_cast<QQuickItem*>(obj);
635 if (widthValid() && !QQuickItemPrivate::get(item)->widthValid())
636 item->setWidth(q->width());
637 if (heightValid() && !QQuickItemPrivate::get(item)->heightValid())
638 item->setHeight(q->height());
639 item->setParentItem(q);
644 QQml_setParent_noEvent(obj, q);
648 if (initialPropertyValues.isUndefined())
651 QQmlComponentPrivate *d = QQmlComponentPrivate::get(component);
652 Q_ASSERT(d && d->engine());
653 QV4::ExecutionEngine *v4 = d->engine()->handle();
655 QV4::Scope scope(v4);
656 QV4::ScopedValue ipv(scope, initialPropertyValues.value());
657 QV4::Scoped<QV4::QmlContext> qmlContext(scope, qmlCallingContext.value());
658 auto incubatorPriv = QQmlIncubatorPrivate::get(incubator);
659 d->initializeObjectWithInitialProperties(qmlContext, ipv, obj, incubatorPriv->requiredProperties());
664 loader->incubatorStateChanged(status);
670 if (status == QQmlIncubator::Loading || status == QQmlIncubator::Null)
673 if (status == QQmlIncubator::Ready) {
674 object = incubator->object();
675 item = qmlobject_cast<QQuickItem*>(object);
676 emit q->itemChanged();
679 }
else if (status == QQmlIncubator::Error) {
680 if (!incubator->errors().isEmpty())
681 QQmlEnginePrivate::warning(qmlEngine(q), incubator->errors());
683 itemContext =
nullptr;
684 delete incubator->object();
686 emit q->itemChanged();
688 if (loadingFromSource)
689 emit q->sourceChanged();
691 emit q->sourceComponentChanged();
693 emit q->progressChanged();
694 if (status == QQmlIncubator::Ready)
701 if (!component || !component->errors().isEmpty()) {
703 QQmlEnginePrivate::warning(qmlEngine(q), component->errors());
705 emit q->sourceChanged();
707 emit q->sourceComponentChanged();
709 emit q->progressChanged();
710 emit q->itemChanged();
718 QQmlContext *creationContext = component->creationContext();
719 if (!creationContext)
720 creationContext = qmlContext(q);
722 QQmlComponentPrivate *cp = QQmlComponentPrivate::get(component);
723 QQmlContext *context = [&](){
725 return creationContext;
726 itemContext =
new QQmlContext(creationContext);
727 itemContext->setContextObject(q);
732 incubator =
new QQuickLoaderIncubator(
this, asynchronous ? QQmlIncubator::Asynchronous : QQmlIncubator::AsynchronousIfNested);
734 component->create(*incubator, context);
736 if (incubator && incubator->status() == QQmlIncubator::Loading)
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
780QQuickLoader::Status QQuickLoader::status()
const
782 Q_D(
const QQuickLoader);
784 return static_cast<Status>(d->status);
787void QQuickLoader::componentComplete()
790 QQuickItem::componentComplete();
791 if (active() && (status() != Ready)) {
792 if (d->loadingFromSource)
793 d->createComponent();
798void QQuickLoader::itemChange(QQuickItem::ItemChange change,
const QQuickItem::ItemChangeData &value)
801 case ItemChildAddedChange:
802 Q_ASSERT(value.item);
803 if (value.item->flags().testFlag(QQuickItem::ItemObservesViewport))
805 value.item->setFlag(QQuickItem::ItemObservesViewport);
810 QQuickItem::itemChange(change, value);
814
815
816
817
818
822
823
824
825
826
827
828
829
830qreal QQuickLoader::progress()
const
832 Q_D(
const QQuickLoader);
838 return d->component->progress();
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876bool QQuickLoader::asynchronous()
const
878 Q_D(
const QQuickLoader);
879 return d->asynchronous;
882void QQuickLoader::setAsynchronous(
bool a)
885 if (d->asynchronous == a)
890 if (!d->asynchronous && isComponentComplete() && d->active) {
891 if (d->loadingFromSource && d->component && d->component->isLoading()) {
893 QUrl currentSource = d->source;
895 d->source = currentSource;
897 }
else if (d->incubator && d->incubator->isLoading()) {
898 d->incubator->forceCompletion();
902 emit asynchronousChanged();
911 const bool needToUpdateWidth = loaderGeometryChanged && q->widthValid();
912 const bool needToUpdateHeight = loaderGeometryChanged && q->heightValid();
914 if (needToUpdateWidth && needToUpdateHeight) {
916
917
918
919 auto *itemPriv = QQuickItemPrivate::get(item);
922 if (itemPriv->width.hasBinding())
923 itemPriv->width.takeBinding();
924 if (itemPriv->height.hasBinding())
925 itemPriv->height.takeBinding();
926 item->setSize(QSizeF(q->width(), q->height()));
927 }
else if (needToUpdateWidth) {
928 item->setWidth(q->width());
929 }
else if (needToUpdateHeight) {
930 item->setHeight(q->height());
938 q->setImplicitSize(getImplicitWidth(), getImplicitHeight());
944
945
946
947
948
949QObject *QQuickLoader::item()
const
951 Q_D(
const QQuickLoader);
955void QQuickLoader::geometryChange(
const QRectF &newGeometry,
const QRectF &oldGeometry)
958 if (newGeometry != oldGeometry) {
961 QQuickItem::geometryChange(newGeometry, oldGeometry);
967 return QQuickLoader::Status::Null;
970 switch (component->status()) {
971 case QQmlComponent::Loading:
972 return QQuickLoader::Status::Loading;
973 case QQmlComponent::Error:
974 return QQuickLoader::Status::Error;
975 case QQmlComponent::Null:
976 return QQuickLoader::Status::Null;
984 case QQmlIncubator::Loading:
985 return QQuickLoader::Status::Loading;
986 case QQmlIncubator::Error:
987 return QQuickLoader::Status::Error;
994 return QQuickLoader::Status::Ready;
996 return source.isEmpty() ? QQuickLoader::Status::Null : QQuickLoader::Status::Error;
1002 auto newStatus = computeStatus();
1003 if (
status != newStatus) {
1005 emit q->statusChanged();
1012 const QQmlComponent::CompilationMode mode = asynchronous
1013 ? QQmlComponent::Asynchronous
1014 : QQmlComponent::PreferSynchronous;
1015 if (QQmlContext *context = qmlContext(q)) {
1016 if (QQmlEngine *engine = context->engine()) {
1017 component.setObject(
new QQmlComponent(
1018 engine, context->resolvedUrl(source), mode, q), q);
1023 qmlWarning(q) <<
"createComponent: Cannot find a QML engine.";
1028#include <moc_qquickloader_p.cpp>
Status
Specifies the status of the QQmlIncubator.
void setInitialState(QObject *) override
Called after the object is first created, but before complex property bindings are evaluated and,...
void statusChanged(Status) override
Called when the status of the incubator changes.
void itemGeometryChanged(QQuickItem *item, QQuickGeometryChange change, const QRectF &oldGeometry) override
void disposeInitialPropertyValues()
void itemImplicitWidthChanged(QQuickItem *) override
qreal getImplicitWidth() const override
QQmlContext * itemContext
void setInitialState(QObject *o)
QQuickLoaderIncubator * incubator
void _q_updateSize(bool loaderGeometryChanged=true)
void itemImplicitHeightChanged(QQuickItem *) override
qreal getImplicitHeight() const override
static QT_BEGIN_NAMESPACE const QQuickItemPrivate::ChangeTypes watchedChanges