Dynamically instantiating a QML object from C++ is well documented, but what I can't find is how to instantiate it with pre-specified values for it's properties.
For example, I am creating a slightly modified SplitView
from C++ like this:
QQmlEngine* engine = QtQml::qmlEngine( this );
QQmlComponent splitComp( engine, QUrl( "qrc:/qml/Sy_splitView.qml" ) );
QObject* splitter = splitComp.create();
splitter->setProperty( "orientation", QVariant::fromValue( orientation ) );
The problem I have is that specifying the orientation
of the SplitView
after it is instantiated causes it's internal layout to break. So, is there a way of creating the SplitView
with the orientation
already specified?
Alternatively I can create both a horizontal and vertical version of SplitView
in separate files and instantiate the appropriate one at runtime - but this is less elegant.
Update
I found QQmlComponent::beginCreate(QQmlContext* publicContext)
:
QQmlEngine* engine = QtQml::qmlEngine( this );
QQmlComponent splitComp( engine, QUrl( "qrc:/qml/Sy_splitView.qml" ) );
QObject* splitter = splitComp.beginCreate( engine->contextForObject( this ) );
splitter->setProperty( "orientation", QVariant::fromValue( orientation ) );
splitter->setParent( parent() );
splitter->setProperty( "parent", QVariant::fromValue( parent() ) );
splitComp.completeCreate();
But it had no effect surprisingly.
There are two ways to create objects dynamically from JavaScript. You can either call Qt. createComponent() to dynamically create a Component object, or use Qt. createQmlObject() to create an object from a string of QML.
A property is an attribute of an object that can be assigned a static value or bound to a dynamic expression. A property's value can be read by other objects. Generally it can also be modified by another object, unless a particular QML type has explicitly disallowed this for a specific property.
Unlike an ordinary property definition, which allocates a new, unique storage space for the property, a property alias connects the newly declared property (called the aliasing property) as a direct reference to an existing property (the aliased property).
Connecting to QML Signals All QML signals are automatically available to C++, and can be connected to using QObject::connect() like any ordinary Qt C++ signal. In return, any C++ signal can be received by a QML object using signal handlers.
For anyone still interested in this problem, in Qt 5 (and so Qt 6), you can also use a custom QQmlContext with QQmlContext::setContextProperty()
to setup external property (orientation
in your case):
QQmlEngine engine;
QQmlContext *context = new QQmlContext(engine.rootContext());
context->setContextProperty("myCustomOrientation", QVariant::fromValue(orientation));
// you can use a 'myCustomOrientation' property inside Sy_splitView.qml, e.g.
// `orientation: myCustomOrientation`
QQmlComponent splitComp(&engine, QUrl("qrc:/qml/Sy_splitView.qml"));
QObject* splitter = splitComp.create(context);
This should allow you to not fiddle with beginCreate
and completeCreate
.
Update:
There is also QQmlComponent::createWithInitialProperties() (from 5.14 onwards) that allows you to create an object and initialize its properties before the creation process finishes.
(And then QQmlApplicationEngine::setInitialProperties() is the application engine's version of the same functionality)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With