Qt nested ListView or can I use TreeView
-
I am working on a project where I want to have a GUI like this:
(I cant figure out how to inset pictures here)
http://i.stack.imgur.com/ZGfps.pngI have a list of my class (the blue one), and it has a list of the green class, so far my C++ structure is good, and I can get data from C++ in qml and vice versa, but I am not sure how to make the GUI work correct, I have triede with nested ListViews, but it seems like that I have no access to the outer ListView model from the inner ListView..
I am pretty new to qml, and yesterday I found the TreeView, but to me it looks like that is only usefull if you have a table structure. Is there some qml that I dont know about that can help me with this?
I have tried this with nested ListViews, the idea beeing that the inner ListView get a object of the green class as model.
ListView { id: userView anchors.fill: parent model: myModel delegate: Rectangle { width: 900 height: 200 Column { id: col anchors.left: parent.left anchors.right: parent.right Item { height: 10 } Text { text: model.type + " " + model.name } Row { spacing: 8 Button { id: addLevel width: 80 text: "Add Level" enabled: setVisible elevation: 1 backgroundColor: Theme.primaryColor onClicked: { myModel.insertLevel(index) } } Button { id: delTariff width: 80 text: "Delete User" enabled: setVisible elevation: 1 backgroundColor: Theme.primaryColor onClicked: { myModel.removeTariff(index) } } Button { id: delLevel width: 80 text: "Delete Level" enabled: setVisible elevation: 1 backgroundColor: Theme.primaryColor onClicked: { myModel.removeLevel(index, 0) } } } Text { text: model.levels } Row { spacing: 8 Repeater { model: myModel.levelStructModel(userView.index) Rectangle { height: 30 width: 30 color: "blue" } } } } }
I also have problem with the program craching after adding or deleting stuff, I tried add the
QQmlEngine::setObjectOwnership(this, QQmlEngine::CppOwnership)
in the contructor of myModel, but without any luck. -
@CocoJoe
Consider classes SomeModel and SubModel:
SomeModel - model for outer ListView;
SubModel - model for inner ListView.
SubModlItem - items in SubModel.SomeModel.h
class SomeModel : public QAbstractListModel { Q_OBJECT public: enum SomeModelRoles{ SOMETEXT = Qt::UserRole+1, SUBMODEL }; //.... // QAbstractItemModel interface public: int rowCount(const QModelIndex &parent) const; QVariant data(const QModelIndex &index, int role) const; QHash<int, QByteArray> roleNames() const; protected: QVector<SubModel*> m_models; QHash<int, QByteArray> m_roles; };
SomeModel.cpp
QVariant SomeModel::data(const QModelIndex &index, int role) const { if(!index.isValid()) return QVariant(); if(role == SOMETEXT) return m_models.at(index.row())->someText(); else if(role == SUBMODEL) return QVariant::fromValue(m_models.at(index.row())); return QVariant(); }
SubModel.h
class SubModel : public QAbstractListModel { //... Q_PROPERTY(QString someText READ someText WRITE setSomeText NOTIFY someTextChanged) public: enum SubModelRoles{ COLOR = Qt::UserRole+1 }; //... // QAbstractItemModel interface public: int rowCount(const QModelIndex &parent) const; QVariant data(const QModelIndex &index, int role) const; QHash<int, QByteArray> roleNames() const; protected: QHash<int, QByteArray> m_roles; QVector<SomeItem*> m_items; QString m_text; };
SubModel.cpp
QVariant SubModel::data(const QModelIndex &index, int role) const { if(!index.isValid()) return QVariant(); if(role == COLOR) return m_items.at(index.row())->color(); return QVariant(); }
some qml file:
ListView { model: someModel // model from C++ spacing: 10 delegate: Component{ Rectangle { width: 200 height: col.height Column{ id: col anchors.left: parent.left anchors.top: parent.top height: list.count*20 + header.height + buttonsRow.height width: parent.width Text{ id: header width: parent.width height: 40 text: someText } Row{ id: buttonsRow anchors.horizontalCenter: parent.horizontalCenter Button{ id: btnAdd text: qsTr("Add") } Button{ id: btnDelete text: qsTr("Delete") } } ListView { id: list model: subModel width: 0.7*parent.width height: count*20 anchors.horizontalCenter: parent.horizontalCenter delegate: Rectangle { width: ListView.view.width height: 20 color: itemColor border.color: "gray" border.width: 1 MouseArea{ anchors.fill: parent onClicked: console.log(parent.color) } } } } } } }
-
@medyakovvit
Finally I got to implement it.
It works like a charm thank you very much..If you want to score some extra kudos on stackoverflow I have posed the same question there http://stackoverflow.com/questions/37671430/qt-nested-listview-or-can-i-use-treeview
If you dont I will answer it myself
-
Hi, I know it's passed a long time, but I was trying to achieve the same thing and looking around this was the most clear code for nested QAbstractListModel classes.
So I just wanted to thank you @medyakovvit for your code.