Accessing delegates in QML from C++
-
I am trying to access the delegate component of the listview in C++ and want to alter it. Like in the code below, I am using QAbstractListModel to provide model to the listview and i have a delegate defined inside the listview which takes two String properties.
Now, at runtime i want to add another property to it from C++, based on the upper layer request. For eg: If i get a request to show 2 textfield along with an imageview in the delegate, in that case i have already two String properties but i dont have an imageview properties inside the delegate. Since, i do not know what exact request will come, i want to add the properties inside the delegate from C++. But i am not sure how to do it.
Any help/suggestion will be appreciated. Below are the code snippet.
listviewComponent.qml
ListView { required model delegate: Text { required property string type required property string size text: type + ", " + size } }
Model.h
class Model { public: Model(const QString& type, const QString& size); QString type() const; QString size() const; private: QString m_type; QString m_size; }; class CustomModel : public QAbstractListModel { Q_OBJECT public: enum Roles { TypeRole = Qt::UserRole + 1, SizeRole }; CustomModel(QObject* parent = 0); void addElement(const Model& pElement); int rowCount(const QModelIndex& parent = QModelIndex()) const; QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const; protected: QHash<int, QByteArray> roleNames() const; private: QList<Model> m_list; };
Model.cpp
Model::Model(const QString& type, const QString& size) : m_type(type), m_size(size) { } QString Model::type() const { return m_type; } QString Model::size() const { return m_size; } CustomModel::CustomModel(QObject* parent) : QAbstractListModel(parent) { } void CustomModel::addElement(const Model &pElement) { beginInsertRows(QModelIndex(), rowCount(), rowCount()); m_list << pElement; endInsertRows(); } int CustomModel::rowCount(const QModelIndex& parent) const { Q_UNUSED(parent); return m_list.count(); } QVariant CustomModel::data(const QModelIndex& index, int role) const { if (index.row() < 0 || index.row() >= m_list.count()) return QVariant(); const Model& mod = m_list[index.row()]; if (role == TypeRole) return mod.type(); else if (role == SizeRole) return mod.size(); return QVariant(); } QHash<int, QByteArray> CustomModel::roleNames() const { QHash<int, QByteArray> roles; roles[TypeRole] = "type"; roles[SizeRole] = "size"; return roles; }
Myclass.h
class myclass : public QObject { Q_OBJECT public: myclass(); inline int createUI(QQmlApplicationEngine &engine){ QQuickWindow *window = qobject_cast<QQuickWindow*>(engine.rootObjects().at(0)); if (!window) { qFatal("Error: Your root item has to be a window."); return -1; } QQuickItem *root = window->contentItem(); window->setWidth(600); window->setHeight(500); QQmlComponent listviewComp(&engine, QUrl(QStringLiteral("qrc:/listviewComponent.qml"))); CustomModel model = new CustomModel(window); model.addElement(Model("Wolf", "Medium")); model.addElement(Model("Polar bear", "Large")); model.addElement(Model("Quoll", "Small")); QQuickItem *listview = qobject_cast<QQuickItem*>(listviewComp.createWithInitialProperties({ {"model", QVariant::fromValue(&model)} })); QQmlEngine::setObjectOwnership(listview, QQmlEngine::CppOwnership); listview->setParentItem(root); listview->setParent(&engine); listview->setProperty("objectName", "lv"); listview->setWidth(200); listview->setHeight(100); listview->setX(250); listview->setY(30); window->show(); return 0; } };
main.cpp
int main(int argc, char *argv[]) { QGuiApplication app(argc, argv); QQmlApplicationEngine engine; const QUrl url(QStringLiteral("qrc:/main.qml")); engine.load(url); QQmlContext *item = engine.rootContext(); myclass myClass; item->setContextProperty("_myClass", &myClass); myClass.createUI(engine); return app.exec(); }