Reputation: 66
I'm looking for a way to dynamically create a component and object, and use the component. It seems like most of the examples available, such as those in the Qt documentation or other StackOverflow posts, are related to using the object returned from createObject(), whereas I want to use the component which contains the (customized) object.
I've stripped out a lot of extraneous detail (e.g. the CustomContainer gets pushed onto/popped off of StackViews), but the following code hopefully illustrates what I'm trying to do... Basically, I would like to have the CustomControl rectangle with foo = 10 and bar = 10, but it seems to load with the defaults instead. There will be multiple "custom control" types and multiple "custom container" objects so I need to be able to support this generically.
The Qt documentation talks about creation contexts, which I assume is my problem, but I'm not sure how to fix this. I'd prefer a purely QML solution, but C++ is fine if that's where the solution lies.
Main.qml:
CustomContainer {
id: myCustomContainer
}
CustomContainer {
id: myOtherCustomContainer
}
function addCustomControl( control, args ) {
var newComponent = Qt.createComponent( control )
var newObj = newComponent.createObject( myCustomContainer, args )
return newComponent
}
myCustomContainer.loaderSource = addCustomControl( "CustomControl.qml", { "foo": 10, "bar": 10 } )
myOtherCustomContainer.loaderSource = addCustomControl( "CustomControl.qml", { "foo": 20, "bar": 20 } )
CustomControl.qml:
Rectangle {
property int foo: 5
property int bar: 5
}
CustomContainer.qml:
Item {
property Component loaderSource
onLoaderSourceChanged: {
myLoader.sourceComponent = loaderSource
}
Loader {
id: myLoader
onSourceComponentChanged: {
doStuff()
}
}
}
Upvotes: 2
Views: 1892
Reputation: 49279
The component does not "contain the object". The component is a prototype for objects to be instantiated. Think of it like a "type" or a class
or struct
in C++ vs an instance of that type.
Your code creates the component, and then creates an object from it with modified values for the properties, but the component still has its default properties, so using it as a source component will produce objects with default properties.
Furthermore, a Loader
will do automatic dynamic instantiation for you. So you don't need to combine both manual and automatic, either do it manually, or leave the loader to do it.
Last, but not least, when components are instantiated by a StackView
they will automatically fill it and their size will be bound to it, so it will automatically change as the StackView
size changes. So just use an Item
and put your content in there and layout it. Only the root item's size will be bound to the StackView
size, its children items will have their own sizes.
Upvotes: 2