Looking for a sample or doc of this pattern in C++ & QML
-
I have an object that is exposed to QML that is written in C++.
I would like this C++ object to be able to provide a model to QML via a property or method.It's not clear to me how to do this because
- my model is built at runtime so it's dissimilar from the examples where a model is created in main.cpp
- my model derives from QAbstractTableModel (which disables copy constructors)
In other words, in C++, it'd be like having a parent method that looks like this...
@MyModel& buildMyModel();@
I'm looking for a sample that goes beyond instantiating a fixed model in main.cpp.
-
Hi and welcome to devnet,
From the top of my head, It should rather be:
@MyModel* buildMyModel();@
-
Thanks.
OK, I will explore this.
-
[quote author="m2512" date="1409086186"]
It's not clear to me how to do this because- my model is built at runtime so it's dissimilar from the examples where a model is created in main.cpp
[/quote]
You might have more luck interpreting the problem as a model that is created in the source, but is populated at runtime. When the program starts, the model will be empty. As data arrives, it is inserted and any attached views learn of new data via the appropriate signals.
- my model is built at runtime so it's dissimilar from the examples where a model is created in main.cpp
-
That's one way to look at it. However, if you have many models or a deep hierarchy of data models it doesn't seem practical to bootstrap them all upfront.
-
In simple terms it's how do you expose a model to QML that is the property of another object already exposed to QML considering that objects deriving from QObject typically disable copy constructors and assignment operators. Not to mention you don't want to be copying heavy models anyway. The suggestion is to expose a slot that returns a pointer to a model but I have yet to see any examples like this. I was looking for a sample or doc of a similar pattern.
-
main.cpp:
@#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QAbstractListModel>
#include <QQmlContext>
#include <QVariant>class Model : public QAbstractListModel
{
Q_OBJECT
public:
Model(QObject *parent = nullptr) : QAbstractListModel(parent) {}
int rowCount(const QModelIndex &parent) const { return 10; }
QVariant data(const QModelIndex &index, int role) const { return QString("string %1").arg(index.row()); }
QHash<int, QByteArray> roleNames() const { return QHash<int, QByteArray> { {Qt::UserRole, "value" } }; }
};class Container : public QObject
{
Q_OBJECT
Q_PROPERTY(QVariant model READ getModel CONSTANT)
public:
Container(QObject *parent = nullptr) : QObject(parent) {m_model = new Model;}
QVariant getModel() const { return QVariant::fromValue(m_model); }
Model *m_model;
};int main(int argc, char *argv[])
{
QGuiApplication app(argc, argv);QQmlApplicationEngine engine; Container container; engine.rootContext()->setContextProperty(QLatin1Literal("container"), &container); engine.load(QUrl(QStringLiteral("qrc:///main.qml"))); return app.exec();
}
#include "main.moc"@
main.qml:
@import QtQuick 2.2
import QtQuick.Window 2.1Window {
visible: true
width: 360
height: 360
ListView {
anchors.fill: parent
model: container.model
delegate: Text {
text: value
}
}
}@Given the stated goal of multiple models, registering a new QML type is probably more appropriate than setting a context property.
-
Excellent! Greatly appreciated - this is what I was looking for :)