QML Property Browser
-
I want to create a QML component similar to this http://doc.qt.digia.com/qq/qq18-propertybrowser.html. At the moment I'm returning a QVariantMap with the property name as the key, and the variant as the thing I want to create an editor component for. I know how to create a ListView with type loaded specific components http://cdumez.blogspot.co.nz/2010/11/heterogeneous-list-model-in-qml.html but how do you access the key or value from the map within a ListView
@
ListView {
model: variantmap
delegate: Text{ text: key??, " ", value??}
}
@ -
I didn't try it yet, but the modelData role can be used to access unnamed objects. Maybe the following will work
@delegate: Text { text: modelData["key"] ...@
-
I don't think a variant map can be used as a model for ListView. I found bug "25195":https://bugreports.qt-project.org/browse/QTBUG-25195 and the response would indicate that what they want me to do is QList<QVariantMap> where each QVariantMap is "key:" keyvalue, "value:" value.
Unfortunately this is a bit long winded and doesn't fit into what I'm being returned so I'll have to hunt down a way to instead fill a ListView dynamically in QML. -
Yes that is right, you cannot use the Map as a model, since it is not an array.
I did some toying around and I came up with converting it to an array in JavaScript to an array and use that as the model for your list.
Made a test-program and that worked.
my datamodel.h:
@
#ifndef DATAMODEL_H
#define DATAMODEL_H#include <QObject>
#include <QVariantMap>class DataModel : public QObject {
Q_OBJECT
Q_PROPERTY(QVariantMap map READ map WRITE setmap NOTIFY mapChanged)
QVariantMap m_map;public:
explicit DataModel(QObject *parent = 0);QVariantMap map() const {
return m_map;
}signals:
void mapChanged(QVariantMap arg);public slots:
void setmap(QVariantMap arg) {
if (m_map != arg) {
m_map = arg;
emit mapChanged(arg);
}
}
};
#endif // DATAMODEL_H
@datamodel.cpp
@
#include "datamodel.h"DataModel::DataModel(QObject *parent) : QObject(parent) {
m_map["Bike"] = QString("slow");
m_map["Car"] = QString("Fast");
m_map["Motor"] = QString("Scary");
}
@Registering it in my view:
@
DataModel datamodel;
viewer.rootContext()->setContextProperty("MyModel", &datamodel);
@And finally the QML:
@
import QtQuick 1.1Rectangle {
width: 360
height: 360property variant jsModel: [] Component.onCompleted: { // Don't know why a temp var is needed // otherwise it does not work var tempModel = jsModel; for (var item in MyModel.map) { var o = new Object; o.key = item; o.value = MyModel.map[item]; tempModel.push(o); } jsModel = tempModel } ListView { anchors.fill: parent model: jsModel delegate: Text {text: modelData.key + ":" + modelData.value; height: paintedHeight} }
}
@Hope it helps
-
I recall reading that you need the temp variable because jsModel ends up being const so you can't update it directly, you can only set a new version. Incidentally, that leads to the next issue of actually updating the values.
I think, in order to create this property editor, I need to take the variant map, construct a QAbstractItemModel from the map and use that in a ListView.