Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

How to create QQmlComponent child instances inside extended QQuickItem (C++)



  • Hi, I need to implement custom QML componont which will create dynamic child elements depending on passed in configuration.
    Simplified example - I need to completely reproduce this QML code using only C++.

    Item {
        Button { text: "hello" }
        CheckBox { text: "click" }
    }
    

    For now I have created custom DynamicView object which extends QQuickItem. What I want to do is to create many child objects inside this object on instantiation.

    1. At what point in this object I can attach and create these child objects dynamically and what I need to be careful of, when destroying this object?

    I was successful to do it in componentComplete() virtual function using QQmlEngine,QQmlComponent,QQuickItem,setParent() like in documentation, BUT seems like it doesn't work the same way as pure QML, because I am using Loader in asynchronous mode and I can see that object creation blocks the main GUI.

    Big picture (what I want to achieve):

    Component {
        id: dynView
        DynamicView {
            customParameter: "create 40 checkboxes, 20 buttons, 30 inputfields" // mockup example
        }
    }
    
    Loader {
        id: loader
        asynchronous: true
    }
    

    When something is triggered, then Loader will destroy previous DynamicView and create a new one with different dynamic parameters.
    And because of many DynamicView children instantiations, it must be done asynchronously.


  • Moderators

    Hi,

    Did you try this and setting QQmlComponent::Asynchronous ?



  • Thanks, yes I tried that and that won't work, because:

    1. The .qml loading/compiling is done only once and that is not the bottleneck, so there is no big benefit of using Asynchronous.

      QQmlComponent *component = new QQmlComponent(engine, QUrl(QStringLiteral("qrc:/MyItem.qml")), QQmlComponent::Asynchronous);
      

    The real "freeze" is at Component instantiation (just simulating many object creation, because I've got powerful PC):

           for (int i = 0; i < 1000; i++) {
               QQuickItem *childItem = qobject_cast<QQuickItem*>(component->create());
               childItem->setParentItem(this);
           }
    

    I need the "create()" part to be Async.

    1. If I do the "Async" stuff manually myself, then there is no flexibility of Loader (asynchronous: true) property, in case I want to create the object somewhere in sync mode. ( Because I like the "correct" solutions) :)


  • I have no idea on your issue, but I recall a method which is in Component type:
    object incubateObject(Item parent, object properties, enumeration mode)

    By noting "incubate" it means the object is created asynchronously, without blocking the GUI.