Benjamin Schwalb
Benjamin Schwalb

Reputation: 1134

Dynamically load/assign objects in QML

I've just started with QML game development using V-Play and coming from java, I stil have problems understanding some basics.

I know how I'd do it in Java, but don't know how it works in QML, so I'll explain it in Java terms:

I have a "base class" with some properties and methods. Then I have modules extending this base class with more specific features. (Like "class Module1 extends BaseModule")

Then I have an object ("ModuleContainer") that contains a Module, but I don't know which one - it's loaded dynamically at runtime. Thus, in Java i'd create a new object like "BaseModule someModule = new Module1()", and can later access it and also replace it (like "someModule = new Module2()").

How could I do that in QML?

I've tried properties, but I haven't found a way to create a new object and then use it. Dynamic creation of objects with an entityManager doesn't quit seem to work for this either.

Upvotes: 1

Views: 601

Answers (1)

Benjamin Schwalb
Benjamin Schwalb

Reputation: 1134

I played around with components a bit and together with a Loader, it's pretty much exactly what I wanted.

Here's my code if anyone else needs something like this:

Basically, I create a baseclass (BaseModule), create two Modules that extend that class (java terms).

In a new class (ModuleSlot), I create two components containing a Module each, that can be dynamically loaded and replaced in the Main code.

Important parts

//define a component and make it accessible from the outside
property Component cmodule1: module1   
Component {
   id: module1
   Module1 {
   }
}

//define a component to hold the component to use (for easier changing)   
property Component dynamicModule: dynamicModuleHolder.cmodule1 

ModuleSlot {
   id:dynamicModuleHolder
}  

//the magic happens here: the defined component is loaded dynamically on runtime, 
when changed, the old one is removed and the new one loaded

Loader {
   sourceComponent:dynamicModule  
}

Full Code

Main.qml:

GameWindow {
id: gameWindow

//licenseKey: "<generate one from http://v-play.net/licenseKey>"

activeScene: scene

width: 640
height: 960


property Component dynamicModule: dynamicModuleHolder.cmodule1
property int activeElement: 1

Scene {


    id: scene

    width: 640
    height: 960



    Loader{
        sourceComponent:dynamicModule
    }

    ModuleSlot {
        id:dynamicModuleHolder
    }

    MouseArea {
           anchors.fill: parent
           onClicked: {
               if(activeElement == 1) {
                   dynamicModule = dynamicModuleHolder.cmodule2
                   activeElement = 2
               } else {
                   dynamicModule = dynamicModuleHolder.cmodule1
                   activeElement = 1
               }
           }
       }



}

}

BaseModule.qml:

Item {
       property int someAttribute: 0
}

Module1.qml/Module2.qml (Module2 only has a different Rectangle)

BaseModule {

    someAttribute: 5 // just to show that Module1 inherits from BaseModule

    Rectangle {
        color: "red"
        width: 50
        height: 50
        x: 200
        y: 200
    }
}

ModuleSlot

Item {

    property Component cmodule1: module1
    property Component cmodule2: module2

    QtObject {
        id: internalSettings
        property color color: "green"
    }

    Component {
        id: module1
        Module1 {

        }
    }

    Component {
        id: module2
        Module2 {

        }
    }
}

Upvotes: 1

Related Questions