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
266QQuickLoader::QQuickLoader(QQuickItem *parent)
267 : QQuickImplicitSizeItem(*(
new QQuickLoaderPrivate), parent)
269 setFlag(ItemIsFocusScope);
272QQuickLoader::~QQuickLoader()
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293bool QQuickLoader::active()
const
295 Q_D(
const QQuickLoader);
299void QQuickLoader::setActive(
bool newVal)
302 if (d->active == newVal)
306 if (newVal ==
true) {
307 if (d->loadingFromSource) {
310 loadFromSourceComponent();
315 d->incubator->clear();
316 delete d->itemContext;
317 d->itemContext =
nullptr;
322 QQmlContext *context = qmlContext(d->object);
324 QQmlContextData::get(context)->clearContextRecursively();
327 QQuickItemPrivate *p = QQuickItemPrivate::get(d->item);
328 p->removeItemChangeListener(d, watchedChanges);
332 d->item->setParentItem(
nullptr);
333 d->item->setVisible(
false);
337 d->object->deleteLater();
343 emit activeChanged();
348
349
350
351
352
353
354
355
356
357
358
359
360QUrl QQuickLoader::source()
const
362 Q_D(
const QQuickLoader);
366void QQuickLoader::setSourceWithoutResolve(
const QUrl &url)
368 setSource(url,
true);
371void QQuickLoader::setSource(
const QUrl &url,
bool needsClear)
374 if (d->source == url)
381 d->loadingFromSource =
true;
386 emit sourceChanged();
389void QQuickLoader::loadFromSource()
392 if (d->source.isEmpty()) {
393 emit sourceChanged();
395 emit progressChanged();
400 if (isComponentComplete()) {
402 d->createComponent();
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
431QQmlComponent *QQuickLoader::sourceComponent()
const
433 Q_D(
const QQuickLoader);
437void QQuickLoader::setSourceComponent(QQmlComponent *comp)
440 if (comp == d->component)
445 d->component.setObject(comp,
this);
446 d->loadingFromSource =
false;
449 loadFromSourceComponent();
451 emit sourceComponentChanged();
454void QQuickLoader::resetSourceComponent()
456 setSourceComponent(
nullptr);
459void QQuickLoader::loadFromSourceComponent()
463 emit sourceComponentChanged();
465 emit progressChanged();
470 if (isComponentComplete())
475QUrl QQuickLoader::setSourceUrlHelper(
const QUrl &unresolvedUrl)
482 QUrl oldUrl = d->source;
484 QUrl sourceUrl = qmlEngine(
this)->handle()->callingQmlContext()->resolvedUrl(unresolvedUrl);
485 if (!sourceUrl.isValid())
491
492
493
494
495
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
554void QQuickLoader::setSource(
const QUrl &source, QJSValue properties)
558 if (!(properties.isArray() || properties.isObject())) {
559 qmlWarning(
this) << QQuickLoader::tr(
"setSource: value is not an object");
563 QUrl sourceUrl = setSourceUrlHelper(source);
565 d->disposeInitialPropertyValues();
566 auto engine = qmlEngine(
this)->handle();
567 d->initialPropertyValues.set(engine, QJSValuePrivate::takeManagedValue(&properties)->asReturnedValue());
568 d->qmlCallingContext.set(engine, engine->qmlContext());
570 setSource(sourceUrl,
false);
573void QQuickLoader::setSource(
const QUrl &source)
577 QUrl sourceUrl = setSourceUrlHelper(source);
579 d->disposeInitialPropertyValues();
580 auto engine = qmlEngine(
this)->handle();
581 d->qmlCallingContext.set(engine, engine->qmlContext());
583 setSource(sourceUrl,
false);
588 initialPropertyValues.clear();
595 if (!q->isComponentComplete() || !component)
598 if (!component->isLoading()) {
601 QObject::connect(component, SIGNAL(statusChanged(QQmlComponent::Status)),
602 q, SLOT(_q_sourceLoaded()));
603 QObject::connect(component, SIGNAL(progressChanged(qreal)),
604 q, SIGNAL(progressChanged()));
606 emit q->progressChanged();
608 emit q->sourceChanged();
610 emit q->sourceComponentChanged();
611 emit q->itemChanged();
617 loader->setInitialState(o);
624 QQuickItem *item = qmlobject_cast<QQuickItem*>(obj);
630 if (widthValid() && !QQuickItemPrivate::get(item)->widthValid())
631 item->setWidth(q->width());
632 if (heightValid() && !QQuickItemPrivate::get(item)->heightValid())
633 item->setHeight(q->height());
634 item->setParentItem(q);
639 QQml_setParent_noEvent(obj, q);
643 if (initialPropertyValues.isUndefined())
646 QQmlComponentPrivate *d = QQmlComponentPrivate::get(component);
647 Q_ASSERT(d && d->engine());
648 QV4::ExecutionEngine *v4 = d->engine()->handle();
650 QV4::Scope scope(v4);
651 QV4::ScopedValue ipv(scope, initialPropertyValues.value());
652 QV4::Scoped<QV4::QmlContext> qmlContext(scope, qmlCallingContext.value());
653 auto incubatorPriv = QQmlIncubatorPrivate::get(incubator);
654 d->initializeObjectWithInitialProperties(qmlContext, ipv, obj, incubatorPriv->requiredProperties());
659 loader->incubatorStateChanged(status);
665 if (status == QQmlIncubator::Loading || status == QQmlIncubator::Null)
668 if (status == QQmlIncubator::Ready) {
669 object = incubator->object();
670 item = qmlobject_cast<QQuickItem*>(object);
671 emit q->itemChanged();
674 }
else if (status == QQmlIncubator::Error) {
675 if (!incubator->errors().isEmpty())
676 QQmlEnginePrivate::warning(qmlEngine(q), incubator->errors());
678 itemContext =
nullptr;
679 delete incubator->object();
681 emit q->itemChanged();
683 if (loadingFromSource)
684 emit q->sourceChanged();
686 emit q->sourceComponentChanged();
688 emit q->progressChanged();
689 if (status == QQmlIncubator::Ready)
696 if (!component || !component->errors().isEmpty()) {
698 QQmlEnginePrivate::warning(qmlEngine(q), component->errors());
700 emit q->sourceChanged();
702 emit q->sourceComponentChanged();
704 emit q->progressChanged();
705 emit q->itemChanged();
713 QQmlContext *creationContext = component->creationContext();
714 if (!creationContext)
715 creationContext = qmlContext(q);
717 QQmlComponentPrivate *cp = QQmlComponentPrivate::get(component);
718 QQmlContext *context = [&](){
720 return creationContext;
721 itemContext =
new QQmlContext(creationContext);
727 incubator =
new QQuickLoaderIncubator(
this, asynchronous ? QQmlIncubator::Asynchronous : QQmlIncubator::AsynchronousIfNested);
729 component->create(*incubator, context);
731 if (incubator && incubator->status() == QQmlIncubator::Loading)
736
737
738
739
740
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
775QQuickLoader::Status QQuickLoader::status()
const
777 Q_D(
const QQuickLoader);
779 return static_cast<Status>(d->status);
782void QQuickLoader::componentComplete()
785 QQuickItem::componentComplete();
786 if (active() && (status() != Ready)) {
787 if (d->loadingFromSource)
788 d->createComponent();
793void QQuickLoader::itemChange(QQuickItem::ItemChange change,
const QQuickItem::ItemChangeData &value)
796 case ItemChildAddedChange:
797 Q_ASSERT(value.item);
798 if (value.item->flags().testFlag(QQuickItem::ItemObservesViewport))
800 value.item->setFlag(QQuickItem::ItemObservesViewport);
805 QQuickItem::itemChange(change, value);
809
810
811
812
813
817
818
819
820
821
822
823
824
825qreal QQuickLoader::progress()
const
827 Q_D(
const QQuickLoader);
833 return d->component->progress();
839
840
841
842
843
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
871bool QQuickLoader::asynchronous()
const
873 Q_D(
const QQuickLoader);
874 return d->asynchronous;
877void QQuickLoader::setAsynchronous(
bool a)
880 if (d->asynchronous == a)
885 if (!d->asynchronous && isComponentComplete() && d->active) {
886 if (d->loadingFromSource && d->component && d->component->isLoading()) {
888 QUrl currentSource = d->source;
890 d->source = currentSource;
892 }
else if (d->incubator && d->incubator->isLoading()) {
893 d->incubator->forceCompletion();
897 emit asynchronousChanged();
906 const bool needToUpdateWidth = loaderGeometryChanged && q->widthValid();
907 const bool needToUpdateHeight = loaderGeometryChanged && q->heightValid();
909 if (needToUpdateWidth && needToUpdateHeight) {
911
912
913
914 auto *itemPriv = QQuickItemPrivate::get(item);
917 if (itemPriv->width.hasBinding())
918 itemPriv->width.takeBinding();
919 if (itemPriv->height.hasBinding())
920 itemPriv->height.takeBinding();
921 item->setSize(QSizeF(q->width(), q->height()));
922 }
else if (needToUpdateWidth) {
923 item->setWidth(q->width());
924 }
else if (needToUpdateHeight) {
925 item->setHeight(q->height());
933 q->setImplicitSize(getImplicitWidth(), getImplicitHeight());
939
940
941
942
943
944QObject *QQuickLoader::item()
const
946 Q_D(
const QQuickLoader);
950void QQuickLoader::geometryChange(
const QRectF &newGeometry,
const QRectF &oldGeometry)
953 if (newGeometry != oldGeometry) {
956 QQuickItem::geometryChange(newGeometry, oldGeometry);
962 return QQuickLoader::Status::Null;
965 switch (component->status()) {
966 case QQmlComponent::Loading:
967 return QQuickLoader::Status::Loading;
968 case QQmlComponent::Error:
969 return QQuickLoader::Status::Error;
970 case QQmlComponent::Null:
971 return QQuickLoader::Status::Null;
979 case QQmlIncubator::Loading:
980 return QQuickLoader::Status::Loading;
981 case QQmlIncubator::Error:
982 return QQuickLoader::Status::Error;
989 return QQuickLoader::Status::Ready;
991 return source.isEmpty() ? QQuickLoader::Status::Null : QQuickLoader::Status::Error;
997 auto newStatus = computeStatus();
998 if (
status != newStatus) {
1000 emit q->statusChanged();
1007 const QQmlComponent::CompilationMode mode = asynchronous
1008 ? QQmlComponent::Asynchronous
1009 : QQmlComponent::PreferSynchronous;
1010 if (QQmlContext *context = qmlContext(q)) {
1011 if (QQmlEngine *engine = context->engine()) {
1012 component.setObject(
new QQmlComponent(
1013 engine, context->resolvedUrl(source), mode, q), q);
1018 qmlWarning(q) <<
"createComponent: Cannot find a QML engine.";
1023#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
Combined button and popup list for selecting options.
static QT_BEGIN_NAMESPACE const QQuickItemPrivate::ChangeTypes watchedChanges