14#include <private/qqmljavascriptexpression_p.h>
15#include <private/qqmlsourcecoordinate_p.h>
17#include <private/qv4functionobject_p.h>
18#include <private/qv4script_p.h>
19#include <private/qv4scopedvalue_p.h>
20#include <private/qv4objectiterator_p.h>
21#include <private/qv4qobjectwrapper_p.h>
22#include <private/qv4jscall_p.h>
27#include <QThreadStorage>
28#include <QtCore/qdebug.h>
29#include <QtCore/qloggingcategory.h>
33 Q_CONSTINIT
thread_local int creationDepth = 0;
284 emit q->statusChanged(
q->status());
294 emit q->progressChanged(
p);
330 qWarning(
"QQmlComponent: Must provide an engine before calling create");
354 propertyName,
o, ddata->outerContext);
403 const bool isValid = prop.
isValid();
416 "%2 does not have a property called %1")
442 if (
d->state.isCompletePending()) {
443 qWarning(
"QQmlComponent: Component destroyed while completion pending");
446 qWarning() <<
"This may have been caused by one of the following errors:";
452 if (
d->state.hasCreator())
457 d->typeData->unregisterCallback(
d);
485 else if (!
d->state.errors.isEmpty())
487 else if (
d->engine && (
d->compilationUnit ||
d->loadedType.isValid()))
683 d->compilationUnit.reset(compilationUnit);
700 qWarning(
"QQmlComponent: Must provide an engine before calling setData");
710 if (typeData->isCompleteOrError()) {
711 d->fromTypeData(typeData);
713 d->typeData = typeData;
714 d->typeData->registerCallback(
d);
729 if (!
d->creationContext.isNull())
730 return d->creationContext->asQQmlContext();
781 QUrl fixedUrl(newUrl);
792 error.setDescription(QQmlComponent::tr(
"Invalid empty URL"));
807 if (
data->isCompleteOrError()) {
816 emit q->statusChanged(
q->status());
929 return d->createWithProperties(
nullptr, initialProperties,
context);
1011 if (!
state.
errors.isEmpty() && lcQmlComponentGeneral().isDebugEnabled()) {
1013 qCDebug(lcQmlComponentGeneral) <<
"QQmlComponent: " <<
e.error.toString();
1018 qWarning(
"QQmlComponent: Cannot create a component in a null context");
1023 qWarning(
"QQmlComponent: Cannot create a component in an invalid context");
1028 qWarning(
"QQmlComponent: Must create component in context from the same QQmlEngine");
1033 qWarning(
"QQmlComponent: Cannot create new component instance before completing the previous");
1041 return e.isTransient;
1046 if (!
q->isReady()) {
1047 qWarning(
"QQmlComponent: Component is not ready");
1052 static const int maxCreationDepth = 10;
1053 if (creationDepth >= maxCreationDepth) {
1054 qWarning(
"QQmlComponent: Component creation is recursing - aborting");
1087 for (
int i = 0, propertyCount = propertyCache->propertyCount();
i < propertyCount; ++
i) {
1088 if (
const QQmlPropertyData *propertyData = propertyCache->property(
i); propertyData->isRequired()) {
1091 info.propertyName = propertyData->name(rv);
1125 deferredData->context->parent(),
1126 deferredData->compilationUnit,
1129 if (!
creator->populateDeferredProperties(
object, deferredData))
1131 deferredData->bindings.clear();
1133 deferredState->push_back(std::move(
state));
1189 auto target = createdComponent;
1195 targetProp =
data->propertyCache->property(propIndex.
coreIndex());
1201 targetProp =
data->propertyCache->property(targetProp->
coreIndex());
1203 auto it = requiredProperties->
find({createdComponent, targetProp});
1204 if (
it != requiredProperties->
end()) {
1205 if (wasInRequiredProperties)
1206 *wasInRequiredProperties =
true;
1207 requiredProperties->
erase(
it);
1209 if (wasInRequiredProperties)
1210 *wasInRequiredProperties =
false;
1230 d->completeCreate();
1264 if (m_prev) *m_prev = m_next;
1265 if (m_next) m_next->m_prev = m_prev;
1282 if (
p->activeObjectCreator) {
1283 a->insertIntoList(
p->activeObjectCreator->componentAttachment());
1288 d->context->addComponentAttached(
a);
1318 auto loadHelper = QQml::makeRefPointer<LoadHelper>(&enginePriv->typeLoader, uri);
1320 auto [moduleStatus,
type] = loadHelper->resolveType(
typeName);
1321 auto reportError = [&](
QString msg) {
1323 error.setDescription(msg);
1324 d->state.errors.push_back(std::move(
error));
1330 } else if (!
type.isValid()) {
1331 reportError(
QLatin1String(R
"(Module "%1" contains no type named "%2")")
1333 } else if (
type.isCreatable()) {
1336 if (
d->progress != 0) {
1340 d->loadedType =
type;
1345 }
else if (
type.isComposite()) {
1347 }
else if (
type.isInlineComponentType()) {
1352 d->inlineComponentName = std::make_unique<QString>(
type.elementName());
1353 Q_ASSERT(!
d->inlineComponentName->isEmpty());
1355 }
else if (
type.isSingleton() ||
type.isCompositeSingleton()) {
1356 reportError(
QLatin1String(R
"(%1 is a singleton, and cannot be loaded)")
1359 reportError(
QLatin1String(
"Could not load %1, as the type is uncreatable")
1389 context =
d->engine->rootContext();
1395 if (!contextData->isValid()) {
1396 qWarning(
"QQmlComponent: Cannot create a component in an invalid context");
1400 if (contextData->engine() !=
d->engine) {
1401 qWarning(
"QQmlComponent: Must create component in context from the same QQmlEngine");
1406 qWarning(
"QQmlComponent: Component is not ready");
1413 if (
d->loadedType.isValid()) {
1417 p->incubateCppBasedComponent(
this,
context);
1423 p->compilationUnit =
d->compilationUnit;
1424 p->enginePriv = enginePriv;
1425 p->creator.reset(
new QQmlObjectCreator(contextData,
d->compilationUnit,
d->creationContext,
p.data()));
1426 p->subComponentToCreate =
d->start;
1428 enginePriv->
incubate(incubator, forContextData);
1480 enginePriv->
incubate(*incubationTask, forContext);
1491#define QmlIncubatorObjectMembers(class, Member) \
1492 Member(class, HeapValue, HeapValue, valuemap) \
1493 Member(class, HeapValue, HeapValue, statusChanged) \
1494 Member(class, Pointer, QmlContext *, qmlContext) \
1495 Member(class, NoMark, QQmlComponentIncubator *, incubator) \
1496 Member(class, NoMark, QV4QPointer<QObject>, parent)
1502 inline void destroy();
1538 i->statusChanged(
s);
1545 i->setInitialState(
o,
d->requiredProperties());
1559 bool needParent =
false;
1560 for (
int ii = 0; ii < functions.
size(); ++ii) {
1570 qmlWarning(me) <<
"Created graphical object was not placed in the graphics scene.";
1628 if (
engine->hasException)
1635 name =
it.nextPropertyNameAsString(
val);
1640 bool isTopLevelProperty =
properties.size() == 1;
1643 object =
object->get(
name);
1644 if (
engine->hasException || !
object) {
1648 if (
engine->hasException) {
1663 if (
engine->hasException) {
1666 }
else if (isTopLevelProperty && requiredProperties) {
1674 engine->hasException =
false;
1686 description +=
QLatin1String(
"\nIt can be set via the alias property %1 from %2\n").
arg(
info.propertyName,
info.fileUrl.toString());
1690 description +=
QLatin1String(
"\nIt can be set via one of the following alias properties:");
1692 description +=
QLatin1String(
"\n- %1 (%2)").
arg(aliasInfo.propertyName, aliasInfo.fileUrl.toString());
1696 error.setDescription(description);
1705#if QT_DEPRECATED_SINCE(6, 3)
1715 qmlWarning(
this) <<
"Unsuitable arguments passed to createObject(). The first argument should "
1716 "be a QObject* or null, and the second argument should be a JavaScript "
1717 "object or a QVariantMap";
1727 parent = qobjectWrapper->object();
1733 qmlWarning(
this) <<
tr(
"createObject: value is not an object");
1741 if (!ctxt) ctxt =
d->engine->rootContext();
1755 if (!valuemap->isUndefined()) {
1758 v4,
qmlContext,
object, valuemap,
d->state.requiredProperties(), rv,
1759 d->state.creator());
1761 if (
d->state.hasUnsetRequiredProperties()) {
1763 for (
const auto &requiredProperty:
std::as_const(*
d->
state.requiredProperties())) {
1772 d->completeCreate();
1778 args->setReturnValue(
object->asReturnedValue());
1874 parent = qobjectWrapper->object();
1881 qmlWarning(
this) <<
tr(
"createObject: value is not an object");
1902 r->setPrototypeOf(
p);
1905 r->d()->valuemap.set(scope.
engine, valuemap);
1915 args->setReturnValue(
r.asReturnedValue());
1964 o->d()->incubator->forceCompletion();
1996 o->d()->statusChanged.set(scope.
engine, argv[0]);
2011 qmlContext.set(internalClass->engine,
nullptr);
2015void QV4::Heap::QmlIncubatorObject::destroy() {
2025 if (!
d()->valuemap.isUndefined()) {
2031 v4, qmlCtxt,
obj,
d()->valuemap, requiredProperties,
o,
2053 f->call(jsCallData);
2061 d()->incubator->incubatorObject.clear();
2064#undef INITIALPROPERTIES_SOURCE
2068#include "moc_qqmlcomponent.cpp"
2069#include "moc_qqmlcomponentattached_p.cpp"
QString toString() const
Returns a deep copy of this string view's data as a QString.
static bool isAbsolutePath(const QString &path)
Returns true if path is absolute; returns false if it is relative.
iterator find(const Key &key)
Returns an iterator pointing to the item with the key in the hash.
iterator erase(const_iterator it)
iterator end() noexcept
Returns an \l{STL-style iterators}{STL-style iterator} pointing to the imaginary item after the last ...
QV4::ExecutionEngine * handle() const
QString arg(Args &&...args) const
qsizetype size() const noexcept
void push_back(parameter_type t)
qsizetype length() const noexcept
const_reference at(qsizetype i) const noexcept
reference emplaceBack(Args &&... args)
void reserve(qsizetype size)
QObject * parent() const
Returns a pointer to the parent object.
static QMetaObject::Connection connect(const QObject *sender, const char *signal, const QObject *receiver, const char *member, Qt::ConnectionType=Qt::AutoConnection)
\threadsafe
void setParent(QObject *parent)
Makes the object a child of parent.
void destroyed(QObject *=nullptr)
This signal is emitted immediately before the object obj is destroyed, after any instances of QPointe...
QQmlComponentAttached(QObject *parent=nullptr)
virtual ~QQmlComponentExtension()
QV4::PersistentValue incubationProto
QQmlComponentExtension(QV4::ExecutionEngine *v4)
void setInitialState(QObject *o) override
Called after the object is first created, but before property bindings are evaluated and,...
void statusChanged(Status s) override
Called when the status of the incubator changes.
QQmlComponentIncubator(QV4::Heap::QmlIncubatorObject *inc, IncubationMode mode)
QV4::PersistentValue incubatorObject
static void complete(QQmlEnginePrivate *enginePriv, ConstructionState *state)
virtual void incubateObject(QQmlIncubator *incubationTask, QQmlComponent *component, QQmlEngine *engine, const QQmlRefPointer< QQmlContextData > &context, const QQmlRefPointer< QQmlContextData > &forContext)
QQmlRefPointer< QV4::ExecutableCompilationUnit > compilationUnit
QObject * beginCreate(QQmlRefPointer< QQmlContextData >)
std::vector< ConstructionState > DeferredState
static QQmlError unsetRequiredPropertyToQQmlError(const RequiredPropertyInfo &unsetRequiredProperty)
std::unique_ptr< QString > inlineComponentName
bool hadTopLevelRequiredProperties() const
bool setInitialProperty(QObject *component, const QString &name, const QVariant &value)
void typeDataProgress(QQmlTypeData *, qreal) override
QObject * doBeginCreate(QQmlComponent *q, QQmlContext *context)
static QQmlComponentPrivate * get(QQmlComponent *c)
QObject * createWithProperties(QObject *parent, const QVariantMap &properties, QQmlContext *context, CreateBehavior behavior=CreateDefault)
void typeDataReady(QQmlTypeData *) override
static void completeDeferred(QQmlEnginePrivate *enginePriv, DeferredState *deferredState)
static void beginDeferred(QQmlEnginePrivate *enginePriv, QObject *object, DeferredState *deferredState)
void loadUrl(const QUrl &newUrl, QQmlComponent::CompilationMode mode=QQmlComponent::PreferSynchronous)
QQmlGuardedContextData creationContext
void fromTypeData(const QQmlRefPointer< QQmlTypeData > &data)
static void setInitialProperties(QV4::ExecutionEngine *engine, QV4::QmlContext *qmlContext, const QV4::Value &o, const QV4::Value &v, RequiredProperties *requiredProperties, QObject *createdComponent, QQmlObjectCreator *creator)
\qmlmethod QtObject Component::createObject(QtObject parent, object properties)
void initializeObjectWithInitialProperties(QV4::QmlContext *qmlContext, const QV4::Value &valuemap, QObject *toCreate, RequiredProperties *requiredProperties)
QQmlRefPointer< QQmlTypeData > typeData
@ CreateWarnAboutRequiredProperties
static QQmlProperty removePropertyFromRequired(QObject *createdComponent, const QString &name, RequiredProperties *requiredProperties, QQmlEngine *engine, bool *wasInRequiredProperties=nullptr)
The QQmlComponent class encapsulates a QML component definition.
bool isError() const
Returns true if status() == QQmlComponent::Error.
friend class QQmlObjectCreator
bool isBound() const
Returns true if the component was created in a QML files that specifies {pragma ComponentBehavior: Bo...
bool isNull() const
Returns true if status() == QQmlComponent::Null.
virtual QObject * beginCreate(QQmlContext *)
Create an object instance from this component, within the specified context.
bool isLoading() const
Returns true if status() == QQmlComponent::Loading.
static QQmlComponentAttached * qmlAttachedProperties(QObject *)
virtual void completeCreate()
This method provides advanced control over component instance creation.
void loadFromModule(QAnyStringView uri, QAnyStringView typeName, QQmlComponent::CompilationMode mode=PreferSynchronous)
Load the QQmlComponent for typeName in the module uri.
QQmlContext * creationContext() const
Returns the QQmlContext the component was created in.
void setInitialProperties(QObject *component, const QVariantMap &properties)
Set top-level properties of the component.
Status status
\qmlproperty enumeration Component::status
QList< QQmlError > errors() const
Returns the list of errors that occurred during the last compile or create operation.
Q_INVOKABLE void incubateObject(QQmlV4Function *)
\qmlmethod object Component::incubateObject(QtObject parent, object properties, enumeration mode)
Q_INVOKABLE QObject * createObject(QObject *parent=nullptr, const QVariantMap &properties={})
QUrl url
\qmlproperty url Component::url The component URL.
CompilationMode
Specifies whether the QQmlComponent should load the component immediately, or asynchonously.
qreal progress
\qmlproperty real Component::progress The progress of loading the component, from 0....
~QQmlComponent() override
Destruct the QQmlComponent.
bool isReady() const
Returns true if status() == QQmlComponent::Ready.
void setData(const QByteArray &, const QUrl &baseUrl)
Sets the QQmlComponent to use the given QML data.
void loadUrl(const QUrl &url)
Load the QQmlComponent from the provided url.
void progressChanged(qreal)
Emitted whenever the component's loading progress changes.
QQmlComponent(QObject *parent=nullptr)
QQmlEngine * engine() const
Returns the QQmlEngine of this component.
Q_INVOKABLE QString errorString() const
\qmlmethod string Component::errorString()
virtual QObject * create(QQmlContext *context=nullptr)
Create an object instance from this component, within the specified context.
QObject * createWithInitialProperties(const QVariantMap &initialProperties, QQmlContext *context=nullptr)
Create an object instance of this component, within the specified context, and initialize its top-lev...
void statusChanged(QQmlComponent::Status)
Emitted whenever the component's status changes.
static QQmlRefPointer< QQmlContextData > get(QQmlContext *context)
The QQmlContext class defines a context within a QML engine.
static QQmlPropertyCache::ConstPtr ensurePropertyCache(QObject *object)
QVector< DeferredData * > deferredData
quint32 explicitIndestructibleSet
static QQmlData * get(QObjectPrivate *priv, bool create)
quint32 rootObjectInCreation
Q_REQUIRED_RESULT QQmlError removeError()
void warning(const QQmlError &)
QQmlTypeLoader typeLoader
void incubate(QQmlIncubator &, const QQmlRefPointer< QQmlContextData > &)
static QQmlEnginePrivate * get(QQmlEngine *e)
void referenceScarceResources()
QQmlDelayedError * erroredBindings
void dereferenceScarceResources()
The QQmlEngine class provides an environment for instantiating QML components.
QQmlContext * rootContext() const
Returns the engine's root context.
QUrl baseUrl() const
Return the base URL for this engine.
QQmlEngine * qmlEngine(const QObject *object)
Returns the QQmlEngine associated with object, if any.
The QQmlError class encapsulates a QML error.
static QQmlIncubatorPrivate * get(QQmlIncubator *incubator)
QScopedPointer< QQmlObjectCreator > creator
QQmlRefPointer< QV4::ExecutableCompilationUnit > compilationUnit
QQmlEnginePrivate * enginePriv
The QQmlIncubator class allows QML objects to be created asynchronously.
void clear()
Clears the incubator.
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.
bool finalize(QQmlInstantiationInterrupt &interrupt)
bool componentHadTopLevelRequiredProperties() const
QObject * create(int subComponentIndex=-1, QObject *parent=nullptr, QQmlInstantiationInterrupt *interrupt=nullptr, int flags=NormalObject)
static void findAliasTarget(QObject *, QQmlPropertyIndex, QObject **, QQmlPropertyIndex *)
static QQmlPropertyPrivate * get(const QQmlProperty &p)
bool writeValueProperty(const QVariant &, QQmlPropertyData::WriteFlags)
The QQmlProperty class abstracts accessing properties on objects created from QML.
bool isValid() const
Returns true if the QQmlProperty refers to a valid property, otherwise false.
int index() const
Return the Qt metaobject index of the property.
QML_ANONYMOUSQObject * object
void registerCallback(TypeDataCallback *)
void unregisterCallback(TypeDataCallback *)
QQmlRefPointer< QQmlTypeData > getType(const QUrl &unNormalizedUrl, Mode mode=PreferSynchronous)
Returns a QQmlTypeData for the specified url.
QObject * createWithQQmlData() const
void reset(T *other=nullptr) noexcept(noexcept(Cleanup::cleanup(std::declval< T * >())))
Deletes the existing object it is pointing to (if any), and sets its pointer to other.
\macro QT_RESTRICTED_CAST_FROM_ASCII
static QString number(int, int base=10)
This is an overloaded member function, provided for convenience. It differs from the above function o...
QByteArray toUtf8() const &
static QUrl fromLocalFile(const QString &localfile)
Returns a QUrl representation of localFile, interpreted as a local file.
QUrl resolved(const QUrl &relative) const
Returns the result of the merge of this URL with relative.
void setFragment(const QString &fragment, ParsingMode mode=TolerantMode)
Sets the fragment of the URL to fragment.
bool isRelative() const
Returns true if the URL is relative; otherwise returns false.
bool isEmpty() const
Returns true if the URL has no data; otherwise returns false.
void setScheme(const QString &scheme)
Sets the scheme of the URL to scheme.
QString toString(FormattingOptions options=FormattingOptions(PrettyDecoded)) const
Returns a string representation of the URL.
QString toLocalFile() const
Returns the path of this URL formatted as a local file path.
int inlineComponentId(const QString &inlineComponentName) const
ObjectType::Data * allocate(Args &&... args)
ExecutionEngine * engine() const
void set(ExecutionEngine *engine, const Value &value)
void statusChanged(QDeclarativeComponent::Status status)
[1]
QSet< QString >::iterator it
AutoParentResult(* AutoParentFunction)(QObject *object, QObject *parent)
Combined button and popup list for selecting options.
\qmltype Particle \inqmlmodule QtQuick.Particles
static const QCssKnownValue properties[NumProperties - 1]
DBusConnection const char DBusError * error
EGLOutputLayerEXT EGLint EGLAttrib value
[5]
#define Q_LOGGING_CATEGORY(name,...)
#define qCDebug(category,...)
GLboolean GLboolean GLboolean b
GLsizei const GLfloat * v
[13]
GLboolean GLboolean GLboolean GLboolean a
[7]
GLint GLsizei GLsizei GLenum GLenum GLsizei void * data
GLdouble GLdouble GLdouble GLdouble q
static qreal component(const QPointF &point, unsigned int i)
QQmlEngine * qmlEngine(const QObject *obj)
QQmlContext * qmlContext(const QObject *obj)
static void removePendingQPropertyBinding(QV4::Value *object, const QString &propertyName, QQmlObjectCreator *creator)
static void QQmlComponent_setQmlParent(QObject *me, QObject *parent)
Q_QML_EXPORT QQmlInfo qmlWarning(const QObject *me)
int qmlConvertSourceCoordinate< quint32, int >(quint32 n)
QScopeGuard< typename std::decay< F >::type > qScopeGuard(F &&f)
[qScopeGuard]
QLatin1StringView QLatin1String
#define QStringLiteral(str)
static QT_BEGIN_NAMESPACE void init(QTextBoundaryFinder::BoundaryType type, QStringView str, QCharAttributes *attributes)
#define V4_DEFINE_EXTENSION(dataclass, datafunction)
#define DECLARE_HEAP_OBJECT(name, base)
#define DECLARE_MARKOBJECTS(class)
#define THROW_TYPE_ERROR()
#define RETURN_UNDEFINED()
#define DEFINE_OBJECT_VTABLE(classname)
#define V4_OBJECT2(DataClass, superClass)
QFileInfo info(fileName)
[8]
QUrl url("example.com")
[constructor-url-reference]
QItemEditorCreatorBase * creator
\inmodule QtCore \reentrant
void clearRequiredProperties()
bool isCompletePending() const
void ensureRequiredPropertyStorage()
QList< AnnotatedQmlError > errors
void appendErrors(const QList< QQmlError > &qmlErrors)
bool hasUnsetRequiredProperties() const
QQmlObjectCreator * creator()
void addPendingRequiredProperty(const QObject *object, const QQmlPropertyData *propData, const RequiredPropertyInfo &info)
void setCompletePending(bool isPending)
void appendCreatorErrors()
QQmlObjectCreator * initCreator(QQmlRefPointer< QQmlContextData > parentContext, const QQmlRefPointer< QV4::ExecutableCompilationUnit > &compilationUnit, const QQmlRefPointer< QQmlContextData > &creationContext)
RequiredProperties * requiredProperties()
static constexpr ReturnedValue null()
MemoryManager * memoryManager
Heap::String * newString(const QString &s=QString())
QQmlError catchExceptionAsQmlError()
Heap::Object * newObject()
QV4::ReturnedValue metaTypeToJS(QMetaType type, const void *data)
QQmlEngine * qmlEngine() const
static Heap::ExecutionContext * qmlContext(Heap::ExecutionContext *ctx)
static ReturnedValue wrap(ExecutionEngine *engine, QObject *object)
static ReturnedValue method_set_statusChanged(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_get_status(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
static V4_NEEDS_DESTROY ReturnedValue method_get_statusChanged(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_get_object(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
void statusChanged(QQmlIncubator::Status)
void setInitialState(QObject *, RequiredProperties *requiredProperties)
static ReturnedValue method_forceCompletion(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
bool hasException() const
static constexpr Value undefinedValue()
static Value fromUInt32(uint i)
QVector< AliasToRequiredInfo > aliasesToRequired
QV4::CompiledData::Location location
IUIAutomationTreeWalker __RPC__deref_out_opt IUIAutomationElement ** parent