Ayberk Özgür
Ayberk Özgür

Reputation: 5300

Qt.createComponent() with existing imported type

I'm trying to create a component of an existing imported type. While this task seems important enough (say when creating components of types found in your own installed QML plugins) it does not seem to be documented. For example, when trying to create a component of MyObject, the workaround is to create a MyObjectComponent.qml file in the application as follows:

import MyPackage 1.0
MyObject{}

Then a component from this object can be created with Qt.createComponent("MyObjectComponent.qml"), but this method seems redundant. Is there a more concise way? I would expect Qt.createComponent("MyObject") to work, but it doesn't.

Upvotes: 2

Views: 1715

Answers (2)

The workaround is briefly mentioned by derM, but it was not clear enough for me. So after some searching and tries see the complete example of how it can be used:

property var headers: [] //will be changed from outside
...
Component {
    id: columnComponent
    TableModelColumn{} //here put the QT type which you want to replicate
}

function generateColumns(headers) {
    let columns = []

    for (let item in headers) {
        let column = columnComponent.createObject(tableModel, { display: headers[item]
                                                  });
        columns.push( column )
    }
    return columns
}

TableModel {
    id: tableModel
    columns: generateColumns(headers)
}

Some explanations: I'm building the table. Want to make more reusable and create columns depend on amount of entries in header variable and the string values inside. Usually it possible to achieve with Repeater, but seems TableModel doesn't allow to pass the one instead of several TableModelColumn directly to the default property. So had to search for workarounds. Maybe my issue can be solved in easier way, but seems it should help to understand derM's answer.

Like a summary: you need to create Component with your type inside, then use it the same way as result of createComponent. And yes.. it still doesn't allow pass the component name in runtime directly.

Upvotes: 0

derM
derM

Reputation: 13701

Qt.createComponent is specified to take a URL as argument, not a type name, so no, there is no way to use Qt.createComponent(Type). But I still don't get, what could be any benefit of this.

  • It gives you no flexibility, since there is no QML-Type to pass around types as values.
  • It gives you no performance benefit, since Qt.createComponent(URL) also uses the engines component cache.

Also there are only few use cases where explicit JS component creation with Qt.createComponent is the right way to go, since QML is a declarative language and most things can be done declarative.

Consider these other ways to create components:

If the a type of a property is Component, you can use standard syntax to create objects. Automatically the object creation stops after the createComponent-step:

property Component someProperty: Item {
    // This Item is not instantiated. Instead only a prototpye/component is created
    // and bound to the property 'someProperty'
}

Wrap the Object you don't want to fully create yet, in a Component:

Component {
    id: myComponent // Use this to reference the Component later.
    Item {
        // This Item is not instantiated. Instead only a prototpye/component is created
        // You can reference it by the *Component's id*
    }
}

This can also be used in property assignment:

property var someProperty: Component {
    Item {
    }
}

TL;DR
No - you can't pass a type to a function in QML, so you can't do it with Qt.createComponent either - especially not, when it is specified to take a URL.
If you still have the feeling that it would be necessary, and any of the other ways to create Components seem to not fulfill your needs, please ask again, and specify what you try to do, and why you think it would be necessary to do so, and we might find a way to solve your real problem.

Upvotes: 0

Related Questions