Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Create QML object from C++ with specified properties

Tags:

c++

qt

qt-quick

qml

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.

like image 627
cmannett85 Avatar asked Oct 30 '13 19:10

cmannett85


People also ask

How do you create an object in QML?

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.

How do you use property in 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.

What is property alias in QML?

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).

How do I connect QML to C++?

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.


1 Answers

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)

like image 55
andrgolubev Avatar answered Sep 22 '22 14:09

andrgolubev