Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. QML and Qt Quick
  4. Qt nested ListView or can I use TreeView
QtWS25 Last Chance

Qt nested ListView or can I use TreeView

Scheduled Pinned Locked Moved Unsolved QML and Qt Quick
c++listviewtreeviewqml
6 Posts 4 Posters 5.8k Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • C Offline
    C Offline
    CocoJoe
    wrote on 27 Jun 2016, 07:08 last edited by
    #1

    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.png

    I 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.

    M 1 Reply Last reply 27 Jun 2016, 11:12
    0
    • C CocoJoe
      27 Jun 2016, 07:08

      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.png

      I 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.

      M Offline
      M Offline
      medyakovvit
      wrote on 27 Jun 2016, 11:12 last edited by
      #2

      @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)
                                      }
                                  }
                              }
                          }
                      }
                  }
              }
      
      1 Reply Last reply
      4
      • C Offline
        C Offline
        CocoJoe
        wrote on 5 Jul 2016, 11:31 last edited by
        #3

        @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

        M 1 Reply Last reply 5 Jul 2016, 11:48
        0
        • C CocoJoe
          5 Jul 2016, 11:31

          @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

          M Offline
          M Offline
          medyakovvit
          wrote on 5 Jul 2016, 11:48 last edited by
          #4

          @CocoJoe Welcome.
          You can answer on stackoverflow)

          1 Reply Last reply
          0
          • S Offline
            S Offline
            spiderdab
            wrote on 20 Sept 2021, 15:09 last edited by
            #5

            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.

            1 Reply Last reply
            0
            • C Offline
              C Offline
              chids
              wrote on 3 Dec 2024, 15:46 last edited by
              #6

              bro ur the goat ive been stuck on this for hours, i think the key was wrappping the whole delegate in a component on the qml side

              1 Reply Last reply
              0

              • Login

              • Login or register to search.
              • First post
                Last post
              0
              • Categories
              • Recent
              • Tags
              • Popular
              • Users
              • Groups
              • Search
              • Get Qt Extensions
              • Unsolved