Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. Need help to create simple model for QTreeModelView
Forum Updated to NodeBB v4.3 + New Features

Need help to create simple model for QTreeModelView

Scheduled Pinned Locked Moved Solved General and Desktop
37 Posts 4 Posters 4.2k Views 3 Watching
  • 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.
  • mrjjM mrjj

    @Please_Help_me_D
    :)
    Ok fair enough but it's also a bit hardcore to fiddle with QAbstractItemModel on
    such a special day :)

    alt text

    Please_Help_me_DP Offline
    Please_Help_me_DP Offline
    Please_Help_me_D
    wrote on last edited by
    #28

    @mrjj Once again I need help
    I set two items to the root item. So here should be one openable item wich after unwrapping should show two other items... but it shows itself instead:

    void MyModel::fetchRootDirectory()
    {
        MyItem* item = new MyItem("first_item");
        MyItem* item1 = new MyItem("first_child");
        MyItem* item2 = new MyItem("second_child");
        item->children.push_back(item1);
        item->children.push_back(item2);
        _items.push_back(item);
    }
    

    Also there is something wrong with highlighting of chosen item

    Here is the updated project

    mrjjM 1 Reply Last reply
    0
    • Please_Help_me_DP Please_Help_me_D

      @mrjj Once again I need help
      I set two items to the root item. So here should be one openable item wich after unwrapping should show two other items... but it shows itself instead:

      void MyModel::fetchRootDirectory()
      {
          MyItem* item = new MyItem("first_item");
          MyItem* item1 = new MyItem("first_child");
          MyItem* item2 = new MyItem("second_child");
          item->children.push_back(item1);
          item->children.push_back(item2);
          _items.push_back(item);
      }
      

      Also there is something wrong with highlighting of chosen item

      Here is the updated project

      mrjjM Offline
      mrjjM Offline
      mrjj
      Lifetime Qt Champion
      wrote on last edited by
      #29

      @Please_Help_me_D
      Hi
      I ran the updated code and it seems to return the same Modelindex for different items so
      that's why you see the top one also as a child and both get selected if you click on one.
      So i think something up with internalpointer but could not spot it.

      It seems like the code from
      https://doc.qt.io/qt-5/qtwidgets-itemviews-editabletreemodel-example.html
      But with some difference with the items and handling.

      Please_Help_me_DP 1 Reply Last reply
      0
      • mrjjM mrjj

        @Please_Help_me_D
        Hi
        I ran the updated code and it seems to return the same Modelindex for different items so
        that's why you see the top one also as a child and both get selected if you click on one.
        So i think something up with internalpointer but could not spot it.

        It seems like the code from
        https://doc.qt.io/qt-5/qtwidgets-itemviews-editabletreemodel-example.html
        But with some difference with the items and handling.

        Please_Help_me_DP Offline
        Please_Help_me_DP Offline
        Please_Help_me_D
        wrote on last edited by
        #30

        @mrjj thank you!
        I just created my model based on editabletreemodel and tried to make it as close as possible and it works now.

        That was the test model. Now I have to create my true model but here is the thing that I cannot tackle.
        The main difference that was between my test model and editabletreemodel is that editabletreemodel had TreeItem* rootItem where were stored information about column header.
        I want to have item that has a public variable that doesn't have the default constructor HighFive::File parentFile;.
        If I do my real model with rootItem to store there information about column header then I will need to somehow initialize HighFive::File parentFile; for rootItem. But rootItem doesn't need to have HighFive::File parentFile; because this is a hdf5 file (I don't need it for columns header).
        What would you suggest me?
        I'm afraid to avoid rootItem for header beacause I feel that this is the staff that made my test model useful.

        mrjjM 1 Reply Last reply
        0
        • Please_Help_me_DP Please_Help_me_D

          @mrjj thank you!
          I just created my model based on editabletreemodel and tried to make it as close as possible and it works now.

          That was the test model. Now I have to create my true model but here is the thing that I cannot tackle.
          The main difference that was between my test model and editabletreemodel is that editabletreemodel had TreeItem* rootItem where were stored information about column header.
          I want to have item that has a public variable that doesn't have the default constructor HighFive::File parentFile;.
          If I do my real model with rootItem to store there information about column header then I will need to somehow initialize HighFive::File parentFile; for rootItem. But rootItem doesn't need to have HighFive::File parentFile; because this is a hdf5 file (I don't need it for columns header).
          What would you suggest me?
          I'm afraid to avoid rootItem for header beacause I feel that this is the staff that made my test model useful.

          mrjjM Offline
          mrjjM Offline
          mrjj
          Lifetime Qt Champion
          wrote on last edited by mrjj
          #31

          @Please_Help_me_D

          Hi
          If you to stuff HighFive::File parentFile into an item, you can so do that with UserRoles.
          each item can have extra data stored in user roles.

          QStandardItem *item = new xxx
          item ->setData(value, Qt::UserRole + 1)
          item ->setData(value2, Qt::UserRole + 2)
          etc

          where value can be anything , including HighFive::File

          So you can create and setup parentFile outside model and simply store it there.

          If that is what you are asking about ?
          Im not 100% sure what you need.

          Please_Help_me_DP 3 Replies Last reply
          1
          • mrjjM mrjj

            @Please_Help_me_D

            Hi
            If you to stuff HighFive::File parentFile into an item, you can so do that with UserRoles.
            each item can have extra data stored in user roles.

            QStandardItem *item = new xxx
            item ->setData(value, Qt::UserRole + 1)
            item ->setData(value2, Qt::UserRole + 2)
            etc

            where value can be anything , including HighFive::File

            So you can create and setup parentFile outside model and simply store it there.

            If that is what you are asking about ?
            Im not 100% sure what you need.

            Please_Help_me_DP Offline
            Please_Help_me_DP Offline
            Please_Help_me_D
            wrote on last edited by
            #32

            @mrjj thank you for hint for userRole. That is useful.
            But also if I add a publica variable of type that doesn't have the default constructor then I must initialaze this variables in constructor. Like:

            MyItem::MyItem(QString pathToFile) :
                parentFile(HighFive::File(pathToFile)){}
            

            I need to store parentFile for all items except rootItem (wich is the item for header). So it makes impossible to create rootItem without such hdf5 file.
            Or maybe there is some solution how to initialize the object with public variable of type that doesn't have the default constructor?

            1 Reply Last reply
            0
            • mrjjM mrjj

              @Please_Help_me_D

              Hi
              If you to stuff HighFive::File parentFile into an item, you can so do that with UserRoles.
              each item can have extra data stored in user roles.

              QStandardItem *item = new xxx
              item ->setData(value, Qt::UserRole + 1)
              item ->setData(value2, Qt::UserRole + 2)
              etc

              where value can be anything , including HighFive::File

              So you can create and setup parentFile outside model and simply store it there.

              If that is what you are asking about ?
              Im not 100% sure what you need.

              Please_Help_me_DP Offline
              Please_Help_me_DP Offline
              Please_Help_me_D
              wrote on last edited by Please_Help_me_D
              #33

              @mrjj it is so hard being slowpoke as me :D
              I needed to add parent item to every child :)

              Four days I worked on that I think but finally everything works :)
              c4271551-d525-486a-bc1a-4e8eba44dbf5-image.png

              1 Reply Last reply
              2
              • mrjjM mrjj

                @Please_Help_me_D

                Hi
                If you to stuff HighFive::File parentFile into an item, you can so do that with UserRoles.
                each item can have extra data stored in user roles.

                QStandardItem *item = new xxx
                item ->setData(value, Qt::UserRole + 1)
                item ->setData(value2, Qt::UserRole + 2)
                etc

                where value can be anything , including HighFive::File

                So you can create and setup parentFile outside model and simply store it there.

                If that is what you are asking about ?
                Im not 100% sure what you need.

                Please_Help_me_DP Offline
                Please_Help_me_DP Offline
                Please_Help_me_D
                wrote on last edited by Please_Help_me_D
                #34

                @mrjj I implemented QAbstractItemModel::fetchMore(...) to upload data when user click on triangle-button to show more items. It works.
                Now I need to do process the data when user click this button to pack (or hide) items. I want to delete infomation from my model when user hides those items (see picture please).
                Is there a function that should work when this event happens or a singnal which is emited when userclick on that button hide items?
                I thought that QAbstractItemModel::rowsRemoved signal should be emited in such situation but it is not. I tried:

                connect(this, &QAbstractItemModel::rowsRemoved, this, &H5Model::pack);
                

                but there is no signal when I push close-button. Or those signals are abstract and I need to emit them and only then catch?
                35e64a56-4447-49af-ae3c-b1fcb7f91a7b-image.png

                1 Reply Last reply
                0
                • M Offline
                  M Offline
                  mpergand
                  wrote on last edited by
                  #35

                  void collapsed(const QModelIndex &index)
                  void expanded(const QModelIndex &index)

                  Please_Help_me_DP 1 Reply Last reply
                  3
                  • M mpergand

                    void collapsed(const QModelIndex &index)
                    void expanded(const QModelIndex &index)

                    Please_Help_me_DP Offline
                    Please_Help_me_DP Offline
                    Please_Help_me_D
                    wrote on last edited by
                    #36

                    @mpergand thank you!

                    1 Reply Last reply
                    0
                    • Please_Help_me_DP Offline
                      Please_Help_me_DP Offline
                      Please_Help_me_D
                      wrote on last edited by
                      #37

                      Now when I have some MyModel I would like to write MyProxyModel which inherited by QAbstractProxyModel (I need to understand how they work that is why I don't want to use QSortFilterProxyModel for now).
                      QAbstractProxyModel inherits QAbstractItemModel so as I understand I must implelement at least the following pure virtual methods from these both abstract models:

                      int QAbstractItemModel::columnCount(const QModelIndex &parent = QModelIndex()) const
                      QVariant QAbstractItemModel::data(const QModelIndex &index, int role = Qt::DisplayRole) const
                      QModelIndex QAbstractItemModel::index(int row, int column, const QModelIndex &parent = QModelIndex()) const
                      QModelIndex QAbstractItemModel::parent(const QModelIndex &index) const
                      int QAbstractItemModel::rowCount(const QModelIndex &parent = QModelIndex()) const
                      QModelIndex QAbstractProxyModel::mapFromSource(const QModelIndex &sourceIndex) const
                      QModelIndex QAbstractProxyModel::mapToSource(const QModelIndex &proxyIndex) const
                      

                      Ok, I don't want to use any kind of a sorting I just want to wrap MyModel to MyProxyModel.
                      In proxy model I just declare the same methods that my source model has and invoke these methods:

                      h5proxymodel.h

                      #ifndef H5PROXYMODEL_H
                      #define H5PROXYMODEL_H
                      
                      #include <QAbstractProxyModel>
                      #include <QSortFilterProxyModel>
                      #include "h5model.h"
                      
                      class H5ProxyModel : public QAbstractProxyModel
                      {
                          Q_OBJECT
                      public:
                          explicit H5ProxyModel(QObject *parent = nullptr);
                          ~H5ProxyModel();
                      
                          QModelIndex	mapFromSource(const QModelIndex &sourceIndex) const override;
                          QModelIndex	mapToSource(const QModelIndex &proxyIndex) const override;
                      
                          void setSourceModel(QAbstractItemModel *sourceModel) override;
                          QAbstractItemModel* getSourceModel();
                      
                          QModelIndex index(int row, int column, const QModelIndex &parent) const override;
                          QModelIndex parent(const QModelIndex &index) const override;
                      
                          int rowCount(const QModelIndex &parent) const override;
                          int columnCount(const QModelIndex &parent) const override;
                      
                          QVariant data(const QModelIndex &index, int role) const override;
                          bool setData(const QModelIndex &index, const QVariant &value, int role) override;
                      
                          QVariant headerData(int section, Qt::Orientation orientation, int role) const override;
                      
                          bool insertRows(int position, int rows,
                                          const QModelIndex &parent = QModelIndex()) override;
                          bool removeRows(int position, int rows,
                                          const QModelIndex &parent = QModelIndex()) override;
                      
                          bool hasChildren(const QModelIndex &parent = QModelIndex()) const override;
                          void expand(const QModelIndex &parent);
                          void collapse(const QModelIndex &parent);
                      
                          Qt::ItemFlags flags(const QModelIndex &index) const override;
                      
                      private:
                          QAbstractItemModel* sourceModel;
                      };
                      
                      #endif // H5PROXYMODEL_H
                      
                      

                      h5proxymodel.cpp

                      #include "h5proxymodel.h"
                      
                      H5ProxyModel::H5ProxyModel(QObject *parent) :
                          QAbstractProxyModel(parent)
                      {
                      
                      }
                      
                      H5ProxyModel::~H5ProxyModel()
                      {
                          delete sourceModel;
                      }
                      
                      QModelIndex H5ProxyModel::mapFromSource(const QModelIndex &sourceIndex) const{
                          if (!sourceIndex.isValid())
                              return QModelIndex();
                      
                          return sourceIndex;
                      }
                      
                      QModelIndex H5ProxyModel::mapToSource(const QModelIndex &proxyIndex) const
                      {
                          if (!proxyIndex.isValid())
                              return QModelIndex();
                      
                          return proxyIndex;
                      }
                      
                      void H5ProxyModel::setSourceModel(QAbstractItemModel *sourceModel){
                          this->sourceModel = sourceModel;
                      }
                      
                      QAbstractItemModel* H5ProxyModel::getSourceModel(){
                          return this->sourceModel;
                      }
                      
                      QModelIndex H5ProxyModel::index(int row, int column, const QModelIndex &parent) const{
                          return this->sourceModel->index(row, column, parent);
                      }
                      
                      QModelIndex H5ProxyModel::parent(const QModelIndex &index) const{
                          return this->sourceModel->parent(index);
                      }
                      
                      int H5ProxyModel::rowCount(const QModelIndex &parent) const{
                          return this->sourceModel->rowCount(parent);
                      }
                      
                      int H5ProxyModel::columnCount(const QModelIndex &parent) const{
                          return this->sourceModel->columnCount(parent);
                      }
                      
                      QVariant H5ProxyModel::data(const QModelIndex &index, int role) const{
                          return sourceModel->data(index, role);
                      }
                      
                      bool H5ProxyModel::setData(const QModelIndex &index, const QVariant &value, int role){
                          return sourceModel->setData(index, value, role);
                      }
                      
                      QVariant H5ProxyModel::headerData(int section, Qt::Orientation orientation, int role) const{
                          return sourceModel->headerData(section, orientation, role);
                      }
                      
                      bool H5ProxyModel::insertRows(int position, int rows, const QModelIndex &parent){
                          return sourceModel->insertRows(position, rows, parent);
                      }
                      bool H5ProxyModel::removeRows(int position, int rows, const QModelIndex &parent){
                          return sourceModel->removeRows(position, rows, parent);
                      }
                      
                      bool H5ProxyModel::hasChildren(const QModelIndex &parent) const{
                          return sourceModel->hasChildren(parent);
                      }
                      
                      void H5ProxyModel::expand(const QModelIndex &parent){
                          static_cast<H5Model*>(sourceModel)->expand(parent);
                      }
                      
                      void H5ProxyModel::collapse(const QModelIndex &parent){
                          static_cast<H5Model*>(sourceModel)->collapse(parent);
                      }
                      
                      Qt::ItemFlags H5ProxyModel::flags(const QModelIndex &index) const{
                          return sourceModel->flags(index);
                      }
                      
                      

                      As you can see all that my proxy does is it redirects commands to source model. But all I see is header in tree view instead of a items (the right picture I see if I set source model to a tree view):
                      480c8262-7d03-4e2e-90d5-e89d8122d98a-image.png
                      Why my logic doesn't work?

                      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