0

I have a C++ plugin system, where a QQmlComponent is created and a qml file is loaded when the user requests a new plugin instance.

Currently I am using setContextProperty() to tell QML about a QObject that is needed for proper initialization.

mEngine->rootContext()->setContextProperty("controller", QVariant::fromValue(mController));
mComponent = new QQmlComponent(mEngine);
mComponent->loadUrl(QUrl{ "qrc:///MyPlugin.qml" });

The problem is, when instantiating a second plugin, both will use the controller of the second one because "controller" is global in QML.

Repeater {
    model: controller.numEntries

Is there a way to set a context property locally (only for the current instance)?

I found solutions using setProperty() or QQmlIncubator and setInitialState(), but they all seem to require an object that was already created from my component. But in my plugin I only define the component, which is loaded in the main application through a Loader item. So, when trying these approaches, I always ended up in setting the value in a copy of the item, but not the one being created in my backend.

How can I get access to a property of the component that is created in QML?

mComponent->findChild<QQuickItem*>("controller");

does not give me any results, even if I defined the property in MyPlugin.qml.

ToeBee
  • 241
  • 4
  • 10
  • So, finally I found a workaround at least. I am sending a signal in my framework when the Loader got the mComponent from my plugin. The signal contains the Loader.item (the created instance of mComponent) and on that i can set the property for my controller (in my plugins slot that is connected to the signal). Not pretty, but at least it works! – ToeBee Jan 26 '18 at 15:33

1 Answers1

0

Maybe you can create a QObject based class and have a slot and instead of using property you can call slot to slot create a new property in c++ and return it to QML

ControllerCreator.h

#ifndef CONTROLLERCREATOR_H
#define CONTROLLERCREATOR_H

#include <QObject>

class ControllerCreator : public QObject {
    Q_OBJECT
  public:
    explicit ControllerCreator(QObject *parent = nullptr);

  signals:

  public slots:
    int propertyCreator();

  private:
    int m_example;
};

#endif // CONTROLLERCREATOR_H

ControllerCreator.cpp

#include "ControllerCreator.h"

ControllerCreator::ControllerCreator(QObject *parent)
    : QObject(parent), m_example(0)
{
}

int ControllerCreator::propertyCreator()
{
    m_example++;
    return m_example;
}

main.cpp

#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QQmlContext>

#include "ControllerCreator.h"

int main(int argc, char *argv[])
{
    QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
    QGuiApplication app(argc, argv);

    QQmlApplicationEngine engine;
    ControllerCreator controllerCreator;
    engine.rootContext()->setContextProperty("creator", &controllerCreator);

    engine.load(QUrl(QLatin1String("qrc:/main.qml")));
    if (engine.rootObjects().isEmpty())
    return -1;

    return app.exec();
}

main.qml

import QtQuick 2.7
import QtQuick.Controls 2.0
import QtQuick.Layouts 1.3

ApplicationWindow {
    visible: true
    width: 640
    height: 480
    title: qsTr("Hello World")
    Column{
        anchors.fill: parent
        Text{
            text: creator.propertyCreator()
            color: "blue"
        }

        Text{
            text: creator.propertyCreator()
            color: "red"

        }

        Text{
            text: creator.propertyCreator()
             color: "green"
        }

    }
}
FONQRI
  • 368
  • 4
  • 13