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.


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.