Reputation: 904
I have a sample project at: https://github.com/jh3010-qt-questions/dynamic_loading
I have read https://doc.qt.io/qt-5/qtqml-javascript-dynamicobjectcreation.html which explains how to load a component dynamically. I have implemented the method described in the documentation in my sample project and it works.
However, because the method is based on global variables, it is unclear how it can work when I am loading many component dynamically and asynchronously. If I wanted to loop over componentNames
and load each component dynamically, how would I construct this asynchronous code?
main.qml
import QtQuick 2.12
import QtQuick.Window 2.12
import QtQuick.Controls 2.12
ApplicationWindow
{
id: appWindow
width: 640
height: 480
visible: true
title: qsTr("Hello World")
property var component
property var componentObject
property var componentNames: [ "ComponentA.qml", "ComponentB.qml", "ComponentC.qml" ]
function finishCreation()
{
console.log( "finish creation" )
if ( component.status === Component.Ready )
{
componentObject = component.createObject( contentColumn );
if ( componentObject === null )
{
// Error Handling
console.log("Error creating object");
}
}
else if ( component.status === Component.Error )
{
// Error Handling
console.log("Error loading component:", component.errorString());
}
}
Connections
{
target: appWindow
Component.onCompleted:
{
component = Qt.createComponent( `qrc:/${componentNames[0]}` );
if ( component.status === Component.Ready )
{
console.log( "ready" )
finishCreation();
}
else
{
component.statusChanged.connect( finishCreation );
}
console.log( "completed window" )
}
}
Item
{
anchors.fill: parent
Column
{
id: contentColumn
// ComponentA {
// }
// ComponentB {
// }
// ComponentC {
// }
}
}
}
qml.qrc
<RCC>
<qresource prefix="/">
<file>main.qml</file>
<file>qtquickcontrols2.conf</file>
<file>ComponentA.qml</file>
<file>ComponentAForm.ui.qml</file>
<file>ComponentB.qml</file>
<file>ComponentBForm.ui.qml</file>
<file>ComponentC.qml</file>
<file>ComponentCForm.ui.qml</file>
</qresource>
</RCC>
Upvotes: 0
Views: 1177
Reputation: 8277
One way to do it is to localize the scope of the functions/variables. You can nest functions within other functions so that they can still reference common variables, but subsequent calls to the outer function won't interfere.
function generateObjects() {
function generateOneObject(name) {
var component
var componentObject
function finishCreation() {
componentObject = component.createObject( contentColumn );
}
component = Qt.createComponent(`qrc:/${name}`)
if (component.status === Component.Ready) {
finishCreation()
} else {
component.statusChanged.connect( finishCreation );
}
}
for (var index in componentNames) {
generateOneObject(componentNames[index])
}
}
Component.onCompleted: {
generateObjects()
}
Upvotes: 1