0
votes

I have a Model which is exposed to the qml context property and it contains a List of Lists. These Lists are created dynamically and are then exposed to the qml context as well.

Model:

#include <QtCore>
#include <QQmlContext>
class Model : public QObject
{
   Q_OBJECT

public:
   Model(QQmlContext* rootContext) {
      rootContext->setContextProperty(QML_NAME, this);
      dataLists.push_back( new DatedValueList(rootContext, "List1", "m"));
      names.push_back("List1");     
   }
   QList<DatedValueList*> dataLists;
   QString QML_NAME = "Model";
   QList<QString> names;

   Q_INVOKABLE QList<QString> getListNames() { return names };
};

DatedValueList:

#include <QObject>
#include <QtCore>
#include <QQmlContext>
class DatedValueList: public QObject, public QList<int>
{
   Q_OBJECT

public:
   DatedValueList(QQmlContext* rootContext, QString i_name, QString i_unit) :   name(i_name), unit(i_unit) 
   {
     rootContext->setContextProperty(name, this);
   }

   QString name; //under this name it is exposed
   QString unit;
   Q_INVOKABLE QString getName() {return name;}
   Q_INVOKABLE QString getUnit() {return unit;}
};

Main:

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

int main(int argc, char *argv[])
{

QGuiApplication app(argc, argv);
QQmlApplicationEngine engine;

//create Controller w/ thread
QQmlContext* rootContext = engine.rootContext();
Model model(rootContext );

//load QML into engine
engine.load(QUrl(QStringLiteral("qrc:/resource/qml/MainWindow.qml")));

return app.exec();
}

in QML I now want to access one of these DatedValueLists like this. MainWindow.qml:

import QtQuick 2.15
import QtQuick.Window 2.15

Window {
   id: mainview
   width: 1800
   height: 768
   visible: true
   flags: Qt.Window

   Timer {
      interval: 1000 // 1 Hz
      running: true
      repeat: true
      onTriggered: {
        console.log( Model.getListNames()[0] ) // Output: List1
        console.log( Model.getListNames()[0].getUnit() ) // Not working
      }
   }
}

The second output line is not working. It is a String and I want to call a function of on it. But how can I cast it or use the String as a qml context id?

1
i modified it, but the problem is far less outlined :/klausDerRiese

1 Answers

1
votes

As minimal requirement you will have to implement a function that returns the DatedValueList on your Model class:

Q_INVOKABLE DatedValueList getList(const QString& name) { return ... };

But this immediately poses a small challenge, since your data structure does not allow lookup and thus should iterate the whole dataLists member.

I think you are better of providing a QVariantMap from your Model class, you can give a name to each list and also obtain the list itself:

//C++
Q_PROPERTY(QVariantMap listMap ...)

//QML
model.listMap.keys()[0]
model.listMap[model.listMap.keys()[0]].getUnit()

But this can even be a bad decision depending on how you want to shape the rest of your UI, which I'm most sure will not be console.log's only ;-)

Another note, context properties should not have a capital for the first letter. You are likely instantiating a Model inside the console.log call instead of referencing the one instantiate in main