MokaT
MokaT

Reputation: 1416

Set loader component by calling C++ function

I'm just wondering if anything like this is possible :

Loader {
    id: loader
    objectName: "loader"
    anchors.centerIn: parent

    sourceComponent: cppWrapper.getCurrentDisplay();
 }

And in C++ :

QDeclarativeComponent currentDisplay;

and

Q_INVOKABLE QDeclarativeComponent getCurrentDisplay() const
{ return currentDisplay; }

I have trouble compiling it (it fails in the moc file compilation), but if it's possible, it can be a real shortcut for me

Upvotes: 2

Views: 1764

Answers (1)

folibis
folibis

Reputation: 12874

Sure, you can create Component in C++ part (as QQmlComponent) and return it to QML part. Simple example (I use Qt 5.4):

First of all I create a class to use it as singleton (just for ease using)

common.h

#include <QObject>
#include <QQmlComponent>

class Common : public QObject
{
    Q_OBJECT
public:
    explicit Common(QObject *parent = 0);
    ~Common();
    Q_INVOKABLE QQmlComponent *getComponent(QObject *parent);
};

common.cpp

QQmlComponent *Common::getComponent(QObject *parent) {
    QQmlEngine *engine = qmlEngine(parent);
    if(engine) {
        QQmlComponent *component = new QQmlComponent(engine, QUrl("qrc:/Test.qml"));
        return component;
    }
    return NULL;
}

Now I create and register my singleton:

main.cpp

#include "common.h"

static QObject *qobject_singletontype_provider(QQmlEngine *engine, QJSEngine *scriptEngine)
{
    Q_UNUSED(engine)
    Q_UNUSED(scriptEngine)
    static Common *common = new Common();
    return common;
}

int main(int argc, char *argv[])
{
    QApplication app(argc, argv);
        qmlRegisterSingletonType<Common>("Test", 1, 0, "Common", qobject_singletontype_provider);
        QQmlApplicationEngine engine;
        engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
        return app.exec();
}

Ok, now we have a singleton and it is very simple to use it in QML:

main.qml

import QtQuick 2.3
import Test 1.0

ApplicationWindow {
    visible: true
    width: 640
    height: 480
    title: qsTr("Hello World")
    id: mainWindow

    Loader {
        id: loader
        objectName: "loader"
        anchors.centerIn: parent
        sourceComponent: Common.getComponent(mainWindow)
    }
}

Also our component we created in C++:

Test.qml

import QtQuick 2.3

Rectangle {
    width: 100
    height: 100
    color: "green"
    border.color: "yellow"
    border.width: 3
    radius: 10
}

Pay attention: all our QML files are in resource but it's just for example and you can put it in any place you want in your case

Upvotes: 5

Related Questions