1

I am trying to make a listview component using QQuickItem and load its model using QAbstractListModel. Below are the steps which i tried.

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; 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(); } 

Problem: Listview is getting displayed but with only one row, but there are 3 rows added in CustomModel. I am assuming some problem with createWithInitialProperties, but couldnt able to crack it.

0

1 Answer 1

2

The problem is caused because "model" is a local variable that will be destroyed as soon as createUI is finished executing, and what you see as the first row is just a cache, you shouldn't actually see a row (it looks like a bug). The solution is to use the heap memory:

// ... 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)} })); // ... 
Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.