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. always show expand icon in tree view
QtWS25 Last Chance

always show expand icon in tree view

Scheduled Pinned Locked Moved Solved General and Desktop
20 Posts 4 Posters 3.6k 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.
  • U Offline
    U Offline
    user4592357
    wrote on 30 May 2019, 12:36 last edited by
    #1

    i have a tree view which is initially populated with items at depth 1.

    these items have children which also need to be populated. however, i only need to populate the item with child items when the item is expanded, i.e. on demand.
    since initially i populate only at first level, the expand icons are not being shown and it's not possible to expand the node.

    how can i show the expand icon?
    one option is to populate each item with dummy node, then delete it when the node is expanded.

    J 1 Reply Last reply 30 May 2019, 14:21
    0
    • A Offline
      A Offline
      arsinte_andrei
      wrote on 30 May 2019, 12:51 last edited by
      #2

      sorry .. I just try to see if I've understood you correctly, you want that the items without children to have a dropdown +? you have no children there that do not make sense at all add some children there and then you will have what to expand... why would you want to do that?? there is a way of doing it but you have to make an extension to the QtreeView class

      U 1 Reply Last reply 30 May 2019, 12:53
      0
      • A arsinte_andrei
        30 May 2019, 12:51

        sorry .. I just try to see if I've understood you correctly, you want that the items without children to have a dropdown +? you have no children there that do not make sense at all add some children there and then you will have what to expand... why would you want to do that?? there is a way of doing it but you have to make an extension to the QtreeView class

        U Offline
        U Offline
        user4592357
        wrote on 30 May 2019, 12:53 last edited by
        #3

        @arsinte_andrei
        yes, that's what i need. i have a lot of child items so i need to retrieve the children only on demand

        A 1 Reply Last reply 30 May 2019, 12:58
        0
        • U user4592357
          30 May 2019, 12:53

          @arsinte_andrei
          yes, that's what i need. i have a lot of child items so i need to retrieve the children only on demand

          A Offline
          A Offline
          arsinte_andrei
          wrote on 30 May 2019, 12:58 last edited by
          #4

          @user4592357 ok... I've understood you if you have millions of data to take from a database and you are working in an embedded device with limited memory then it makes sense....
          what you can do is to load al the parents and 1 child for each parent like that you will have all the + sign there... (or you can load a limit of 10)
          and then process the rest when the actual click is made on the respective parent - load all its children. how about this??

          U 1 Reply Last reply 30 May 2019, 12:59
          0
          • A arsinte_andrei
            30 May 2019, 12:58

            @user4592357 ok... I've understood you if you have millions of data to take from a database and you are working in an embedded device with limited memory then it makes sense....
            what you can do is to load al the parents and 1 child for each parent like that you will have all the + sign there... (or you can load a limit of 10)
            and then process the rest when the actual click is made on the respective parent - load all its children. how about this??

            U Offline
            U Offline
            user4592357
            wrote on 30 May 2019, 12:59 last edited by
            #5

            @arsinte_andrei
            retrieving the children is still a query to the database. so i thought inserting/removing a dummy node would be much faster

            A 1 Reply Last reply 30 May 2019, 13:04
            0
            • U user4592357
              30 May 2019, 12:59

              @arsinte_andrei
              retrieving the children is still a query to the database. so i thought inserting/removing a dummy node would be much faster

              A Offline
              A Offline
              arsinte_andrei
              wrote on 30 May 2019, 13:04 last edited by
              #6

              @user4592357
              sorry are your concern about network speeds those days??
              how big database do we speak about?
              what database will you have MySQL or SQLite (the concept not the actual name)??
              what device has to run this code? is it mobile??

              we are doping optimizations where optimisations make sense but if you have to query just a few hundreds of database entries... then all this can be kept in a QHash and work with it from there...

              J 1 Reply Last reply 30 May 2019, 14:39
              0
              • U user4592357
                30 May 2019, 12:36

                i have a tree view which is initially populated with items at depth 1.

                these items have children which also need to be populated. however, i only need to populate the item with child items when the item is expanded, i.e. on demand.
                since initially i populate only at first level, the expand icons are not being shown and it's not possible to expand the node.

                how can i show the expand icon?
                one option is to populate each item with dummy node, then delete it when the node is expanded.

                J Offline
                J Offline
                JonB
                wrote on 30 May 2019, 14:21 last edited by JonB
                #7

                @user4592357

                one option is to populate each item with dummy node, then delete it when the node is expanded.

                Yes, this is a better opton than actually querying a database. I am not familiar with the workings of the icon in QTreeView. However, in the case of Windows Explorer itself, that works by always placing a + icon expansion against each directory, as though it knew it is expandable, and then only actually doing the expansion if the user clicks on it. At which point it may go to no-icon if there turn out to be no children. This certainly happens on "slow" directory devices, such as a network directory.

                A 1 Reply Last reply 30 May 2019, 14:36
                1
                • J JonB
                  30 May 2019, 14:21

                  @user4592357

                  one option is to populate each item with dummy node, then delete it when the node is expanded.

                  Yes, this is a better opton than actually querying a database. I am not familiar with the workings of the icon in QTreeView. However, in the case of Windows Explorer itself, that works by always placing a + icon expansion against each directory, as though it knew it is expandable, and then only actually doing the expansion if the user clicks on it. At which point it may go to no-icon if there turn out to be no children. This certainly happens on "slow" directory devices, such as a network directory.

                  A Offline
                  A Offline
                  arsinte_andrei
                  wrote on 30 May 2019, 14:36 last edited by
                  #8

                  @JonB and this is what I call a stupid thing there in windows - I'm glad I'm using GNU/Linux - we think a lot more about user experience then microshit. doing like that you mislead the user - the user will think that there is something there when in fact is empty. Try to be fair with your user... you do not like it when something is showing you that it has many items or file inside a folder and then you click on it, wait to load and after you loaded it you and it empty... this is wrong..

                  • Hey I have something to present to you!!
                  • Waw... nice let me see what is it??
                    -hm....
                    hm....
                    Sorry but nothing there.....
                    -What?? Why did you do that to me??
                  J 1 Reply Last reply 30 May 2019, 14:42
                  0
                  • A arsinte_andrei
                    30 May 2019, 13:04

                    @user4592357
                    sorry are your concern about network speeds those days??
                    how big database do we speak about?
                    what database will you have MySQL or SQLite (the concept not the actual name)??
                    what device has to run this code? is it mobile??

                    we are doping optimizations where optimisations make sense but if you have to query just a few hundreds of database entries... then all this can be kept in a QHash and work with it from there...

                    J Offline
                    J Offline
                    JonB
                    wrote on 30 May 2019, 14:39 last edited by JonB
                    #9

                    @arsinte_andrei
                    @user4592357
                    Alternatively, I presume you can sub-class your model and override https://doc.qt.io/qt-5/qabstractitemmodel.html#hasChildren and have that return true initially? I assume that is used for the QTreeView to decide whether to show + expander. Then when you actually get the signal to expand later you do the proper database look up and adjust your model/what it returns for hasChildren() to be correct. If that works it might (or might not) be preferable to creating a dummy child.

                    I note that for a QTreeWidget there is https://doc.qt.io/qt-5/qtreewidgetitem.html#childIndicatorPolicy and enum QTreeWidgetItem::ChildIndicatorPolicy

                    QTreeWidgetItem::ShowIndicator 0 The controls for expanding and collapsing will be shown for this item even if there are no children.

                    which might have done fine for you. Anything that is doable for QTreeWidget is doable for QTreeView, but I don't know how much/what its code is

                    1 Reply Last reply
                    1
                    • A arsinte_andrei
                      30 May 2019, 14:36

                      @JonB and this is what I call a stupid thing there in windows - I'm glad I'm using GNU/Linux - we think a lot more about user experience then microshit. doing like that you mislead the user - the user will think that there is something there when in fact is empty. Try to be fair with your user... you do not like it when something is showing you that it has many items or file inside a folder and then you click on it, wait to load and after you loaded it you and it empty... this is wrong..

                      • Hey I have something to present to you!!
                      • Waw... nice let me see what is it??
                        -hm....
                        hm....
                        Sorry but nothing there.....
                        -What?? Why did you do that to me??
                      J Offline
                      J Offline
                      JonB
                      wrote on 30 May 2019, 14:42 last edited by JonB
                      #10

                      @arsinte_andrei

                      wait to load and after you loaded it you and it empty... this is wrong..

                      To be fair, that is precisely what you [EDIT: I now realize that was the OP and not you] are asking for: show it as though it's expandable to start with to avoid having to look, and then maybe have to take that away when user later clicks and finds it's not expandable!

                      A 1 Reply Last reply 30 May 2019, 14:49
                      0
                      • J JonB
                        30 May 2019, 14:42

                        @arsinte_andrei

                        wait to load and after you loaded it you and it empty... this is wrong..

                        To be fair, that is precisely what you [EDIT: I now realize that was the OP and not you] are asking for: show it as though it's expandable to start with to avoid having to look, and then maybe have to take that away when user later clicks and finds it's not expandable!

                        A Offline
                        A Offline
                        arsinte_andrei
                        wrote on 30 May 2019, 14:49 last edited by
                        #11

                        @JonB
                        this is what I've said before that one of the solutions is to subclass the qtreeview (to make an extension - in my first post) or he has any way to make a query to the database server to get the parents.. so .. why not to ask for the first child of each or for the first 10children of each parent?
                        but in order to give good advice on how this can be best implemented, he has to answer the questions from here

                        sorry are your concern about network speeds those days??
                        how big database do we speak about?
                        what database will you have MySQL or SQLite (the concept not the actual name)??
                        what device has to run this code? is it mobile??
                        

                        and based on his I can think of a good and "proper" solution - or to put it even better - How I will do it myself...

                        1 Reply Last reply
                        0
                        • U Offline
                          U Offline
                          user4592357
                          wrote on 30 May 2019, 18:20 last edited by user4592357
                          #12

                          @arsinte_andrei

                          1. the application should handle databases with 40+ million records (to show in gui)
                          2. it's SQLite
                          3. it's a desktop application

                          @JonB
                          i tried to implement that idea but it's not only changing childCount(), more functions need to be overriden. don't know if it's worth it, or i should just go with making use of the dummy node.

                          in my case i do have children items for each parent node, so it won't mislead the user

                          1 Reply Last reply
                          0
                          • Christian EhrlicherC Offline
                            Christian EhrlicherC Offline
                            Christian Ehrlicher
                            Lifetime Qt Champion
                            wrote on 30 May 2019, 18:23 last edited by
                            #13

                            hasChildren() doesn't help here / is not needed to be touched - you have to reimplement rowCount()

                            Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
                            Visit the Qt Academy at https://academy.qt.io/catalog

                            U 1 Reply Last reply 31 May 2019, 12:50
                            2
                            • Christian EhrlicherC Christian Ehrlicher
                              30 May 2019, 18:23

                              hasChildren() doesn't help here / is not needed to be touched - you have to reimplement rowCount()

                              U Offline
                              U Offline
                              user4592357
                              wrote on 31 May 2019, 12:50 last edited by user4592357
                              #14

                              @Christian-Ehrlicher
                              i know right, and that's what i did, only for me it's called childCount(), but that led to app crash (because removeChidlren() was called somewhere)

                              1 Reply Last reply
                              0
                              • Christian EhrlicherC Offline
                                Christian EhrlicherC Offline
                                Christian Ehrlicher
                                Lifetime Qt Champion
                                wrote on 1 Jun 2019, 06:34 last edited by
                                #15

                                There is no childCount() function anywhere in a model - seems like you're mixing QTreeWidget with QTreeView... please show some code...

                                Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
                                Visit the Qt Academy at https://academy.qt.io/catalog

                                U 1 Reply Last reply 1 Jun 2019, 07:31
                                0
                                • Christian EhrlicherC Christian Ehrlicher
                                  1 Jun 2019, 06:34

                                  There is no childCount() function anywhere in a model - seems like you're mixing QTreeWidget with QTreeView... please show some code...

                                  U Offline
                                  U Offline
                                  user4592357
                                  wrote on 1 Jun 2019, 07:31 last edited by user4592357 6 Jan 2019, 07:31
                                  #16

                                  @Christian-Ehrlicher
                                  i meant the childCount() method of the tree item.
                                  okay, now i overrode QAbstractItemModel::rowCount() instead, but no luck. the expand icon isn't shown

                                  class TreeItem : public TreeItemBase
                                  {
                                  public:
                                  	TreeItem(const QList<QVariant> &data, TreeItemBase *parent = nullptr)
                                  		: TreeItemBase(data, parent)
                                  	{
                                  	}
                                  
                                  	TreeItem(const QString data, TreeItemBase *parent = nullptr)
                                  		: TreeItemBase(data, parent)
                                  	{
                                  	}
                                  
                                  	void setExpanded(bool bExpanded)
                                  	{
                                  		m_bExpanded = bExpanded;
                                  	}
                                  
                                  	bool isExpanded() const
                                  	{
                                  		return m_bExpanded;
                                  	}
                                  
                                  private:
                                  	bool m_bExpanded = false;
                                  
                                  }; // class TreeItem
                                  
                                  class TreeModel : public TreeModelBase
                                  {
                                  public:
                                  	int rowCount(const QModelIndex &parent /* = QModelIndex() */) const
                                  	{
                                  		auto pNode = dynamic_cast<TreeItem *>(getItem(parent));
                                  		if (!pNode) return 0;
                                  
                                  		return pNode->isExpanded()
                                  			? TreeModelBase::rowCount(parent)
                                  			: 1;
                                  	}
                                  
                                  }; // class TreeModel
                                  
                                  // later...
                                  
                                  void Tree::onItemExpanded(const QModelIndex &index)
                                  {
                                  	// first, remove everything
                                  	m_pTreeVewModel->clearChildren(index);
                                  	
                                  	auto pExpandedItem = m_pTreeVewModel->getItem(index);
                                  	if (!pExpandedItem) return;
                                  
                                  	static_cast<TreeItem *>(pExpandedItem)->setExpanded(true);
                                  
                                      // ...
                                  }
                                  
                                  1 Reply Last reply
                                  0
                                  • Christian EhrlicherC Offline
                                    Christian EhrlicherC Offline
                                    Christian Ehrlicher
                                    Lifetime Qt Champion
                                    wrote on 1 Jun 2019, 07:57 last edited by
                                    #17

                                    Again: childCount() is from QTreeWidgetItem, rowCount() from a model - these are two distinct approaches which can't be mixed.

                                    Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
                                    Visit the Qt Academy at https://academy.qt.io/catalog

                                    U 1 Reply Last reply 1 Jun 2019, 08:10
                                    0
                                    • Christian EhrlicherC Christian Ehrlicher
                                      1 Jun 2019, 07:57

                                      Again: childCount() is from QTreeWidgetItem, rowCount() from a model - these are two distinct approaches which can't be mixed.

                                      U Offline
                                      U Offline
                                      user4592357
                                      wrote on 1 Jun 2019, 08:10 last edited by
                                      #18

                                      @Christian-Ehrlicher
                                      i got it, and that's why i overrode rowCount() in the above post

                                      1 Reply Last reply
                                      0
                                      • Christian EhrlicherC Offline
                                        Christian EhrlicherC Offline
                                        Christian Ehrlicher
                                        Lifetime Qt Champion
                                        wrote on 1 Jun 2019, 11:28 last edited by
                                        #19

                                        This is working perfectly for me (don't take a look for the memleaks, it's a proof-of-concept):

                                        class TreeItem
                                        {
                                        public:
                                          TreeItem(const QString &data, TreeItem *parent = nullptr)
                                            : m_data(data)
                                            , m_parent(parent)
                                          {}
                                          void setExpanded(bool bExpanded) { m_bExpanded = bExpanded; }
                                          bool isExpanded() const { return m_bExpanded; }
                                          void addChild(TreeItem *item) { m_children.push_back(item); }
                                          int childCount() const { return m_bExpanded ? m_children.size() : 1; }
                                          QVariant data() const { return m_data; }
                                          TreeItem *parent() const { return m_parent; }
                                          int indexOf(TreeItem *item) const { return m_children.indexOf(item); }
                                          TreeItem *childAt(int row) const { return (row >= 0 && row < m_children.size()) ? m_children.at(row) : nullptr; }
                                        private:
                                          QVariant m_data;
                                          TreeItem *m_parent;
                                          QVector<TreeItem*> m_children;
                                          bool m_bExpanded = true;
                                        };
                                        
                                        class TreeModel final : public QAbstractItemModel
                                        {
                                          TreeItem *getItem(const QModelIndex &idx) const
                                          {
                                            return idx.isValid() ? static_cast<TreeItem*>(idx.internalPointer()) : m_root;
                                          }
                                        public:
                                          void setRootItem(TreeItem *root) { m_root = root; }
                                          int columnCount(const QModelIndex &parent = QModelIndex()) const override { Q_UNUSED(parent); return 1; }
                                          int rowCount(const QModelIndex &parent = QModelIndex()) const override
                                          {
                                            const TreeItem *pNode = getItem(parent);
                                            int ret = pNode ? pNode->childCount() : 0;
                                            return ret;
                                          }
                                        
                                          QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override
                                          {
                                            if (role != Qt::DisplayRole)
                                              return QVariant();
                                            TreeItem *pNode = getItem(index);
                                            return pNode ? pNode->data() : QVariant();
                                          }
                                        
                                          QModelIndex parent(const QModelIndex &child) const override
                                          {
                                            TreeItem *pNode = getItem(child);
                                            TreeItem *pParent = pNode ? pNode->parent() : nullptr;
                                            if (pParent == m_root || pParent == nullptr)
                                              return QModelIndex();
                                            TreeItem *pGrandParent = pParent->parent();
                                            int row = pGrandParent->indexOf(pParent);
                                            return createIndex(row, 0, pGrandParent);
                                          }
                                        
                                          QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const override
                                          {
                                            const TreeItem *pParent = getItem(parent);
                                            TreeItem *pNode = pParent->childAt(row);
                                            if (!pNode)
                                              return QModelIndex();
                                            return createIndex(row, column, pNode);
                                          }
                                        private:
                                          TreeItem *m_root = nullptr;
                                        }; // class TreeModel
                                        
                                        int main(int argc, char **argv)
                                        {
                                            QApplication app(argc, argv);
                                        
                                            TreeModel *model = new TreeModel;
                                            TreeItem *rootItem = new TreeItem(QString("root"));
                                            model->setRootItem(rootItem);
                                            for (int i = 0; i < 4; ++i)
                                            {
                                              auto item = new TreeItem(QString::number(i), rootItem);
                                              item->setExpanded(i % 2 == 0);
                                              rootItem->addChild(item);
                                            }
                                        
                                            QTreeView *tv = new QTreeView;
                                            tv->setModel(model);
                                            tv->show();
                                        
                                            return app.exec();
                                        }
                                        

                                        Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
                                        Visit the Qt Academy at https://academy.qt.io/catalog

                                        U 1 Reply Last reply 1 Jun 2019, 12:58
                                        0
                                        • Christian EhrlicherC Christian Ehrlicher
                                          1 Jun 2019, 11:28

                                          This is working perfectly for me (don't take a look for the memleaks, it's a proof-of-concept):

                                          class TreeItem
                                          {
                                          public:
                                            TreeItem(const QString &data, TreeItem *parent = nullptr)
                                              : m_data(data)
                                              , m_parent(parent)
                                            {}
                                            void setExpanded(bool bExpanded) { m_bExpanded = bExpanded; }
                                            bool isExpanded() const { return m_bExpanded; }
                                            void addChild(TreeItem *item) { m_children.push_back(item); }
                                            int childCount() const { return m_bExpanded ? m_children.size() : 1; }
                                            QVariant data() const { return m_data; }
                                            TreeItem *parent() const { return m_parent; }
                                            int indexOf(TreeItem *item) const { return m_children.indexOf(item); }
                                            TreeItem *childAt(int row) const { return (row >= 0 && row < m_children.size()) ? m_children.at(row) : nullptr; }
                                          private:
                                            QVariant m_data;
                                            TreeItem *m_parent;
                                            QVector<TreeItem*> m_children;
                                            bool m_bExpanded = true;
                                          };
                                          
                                          class TreeModel final : public QAbstractItemModel
                                          {
                                            TreeItem *getItem(const QModelIndex &idx) const
                                            {
                                              return idx.isValid() ? static_cast<TreeItem*>(idx.internalPointer()) : m_root;
                                            }
                                          public:
                                            void setRootItem(TreeItem *root) { m_root = root; }
                                            int columnCount(const QModelIndex &parent = QModelIndex()) const override { Q_UNUSED(parent); return 1; }
                                            int rowCount(const QModelIndex &parent = QModelIndex()) const override
                                            {
                                              const TreeItem *pNode = getItem(parent);
                                              int ret = pNode ? pNode->childCount() : 0;
                                              return ret;
                                            }
                                          
                                            QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override
                                            {
                                              if (role != Qt::DisplayRole)
                                                return QVariant();
                                              TreeItem *pNode = getItem(index);
                                              return pNode ? pNode->data() : QVariant();
                                            }
                                          
                                            QModelIndex parent(const QModelIndex &child) const override
                                            {
                                              TreeItem *pNode = getItem(child);
                                              TreeItem *pParent = pNode ? pNode->parent() : nullptr;
                                              if (pParent == m_root || pParent == nullptr)
                                                return QModelIndex();
                                              TreeItem *pGrandParent = pParent->parent();
                                              int row = pGrandParent->indexOf(pParent);
                                              return createIndex(row, 0, pGrandParent);
                                            }
                                          
                                            QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const override
                                            {
                                              const TreeItem *pParent = getItem(parent);
                                              TreeItem *pNode = pParent->childAt(row);
                                              if (!pNode)
                                                return QModelIndex();
                                              return createIndex(row, column, pNode);
                                            }
                                          private:
                                            TreeItem *m_root = nullptr;
                                          }; // class TreeModel
                                          
                                          int main(int argc, char **argv)
                                          {
                                              QApplication app(argc, argv);
                                          
                                              TreeModel *model = new TreeModel;
                                              TreeItem *rootItem = new TreeItem(QString("root"));
                                              model->setRootItem(rootItem);
                                              for (int i = 0; i < 4; ++i)
                                              {
                                                auto item = new TreeItem(QString::number(i), rootItem);
                                                item->setExpanded(i % 2 == 0);
                                                rootItem->addChild(item);
                                              }
                                          
                                              QTreeView *tv = new QTreeView;
                                              tv->setModel(model);
                                              tv->show();
                                          
                                              return app.exec();
                                          }
                                          
                                          U Offline
                                          U Offline
                                          user4592357
                                          wrote on 1 Jun 2019, 12:58 last edited by user4592357 6 Jan 2019, 14:58
                                          #20

                                          @Christian-Ehrlicher
                                          EDIT: don't bother to look at the code, i found the issue. auto pNode = dynamic_cast<TreeItem *>(getItem(parent)); always returned nullptr. so i just removed the rowCount() override from the model. childCount() of the item is enough.

                                          i have a base class tree and a derived one, from where i'm deleting the old tree model and using the new customized one. but in that case the view isn't populated. here's what i have:

                                          class TreeModelBase : public QAbstractItemModel
                                          {
                                          	Q_OBJECT
                                          
                                          public:
                                          	TreeModelBase(const QString &data, QObject *parent = 0);
                                          	TreeModelBase(const QList<QVariant> &columnsData, QObject *parent = 0);
                                                  ~TreeModelBase() {delete rootItem;}
                                          
                                          	virtual QVariant data(const QModelIndex &index, int role) const;
                                          	virtual bool setData(const QModelIndex &index, const QVariant &value, int role);
                                          	virtual Qt::ItemFlags flags(const QModelIndex &index) const;
                                          	virtual QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const;
                                          	
                                          	virtual QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const;
                                          	virtual QModelIndex parent(const QModelIndex &index) const;
                                          
                                          	virtual int rowCount(const QModelIndex &parent = QModelIndex()) const;	
                                          	virtual int columnCount(const QModelIndex &parent = QModelIndex()) const;
                                          		
                                          	QModelIndex getIndex(const TreeItemBase *node, int column = 0) const;
                                          	void insertChild(TreeItemBase *parent, TreeItemBase *child, bool notify = true,	int row = -1);
                                          	TreeItemBase* getItem(const QModelIndex &index) const;
                                          	void clearChildren(const QModelIndex &parent);
                                          	void resetModel();
                                          	void resetModel(const QList<QVariant> &columnsData);
                                          	void updateModel();
                                          
                                          	TreeItemBase* getRootItem() const	{ return rootItem; }
                                          private:
                                          	void setupModelData(const QStringList &lines, TreeItemBase *parent);
                                          	TreeItemBase* rootItem;
                                          };
                                          
                                          TreeModelBase::TreeModelBase(const QString &data, QObject *parent) : QAbstractItemModel(parent)
                                          {
                                          	QList<QVariant> rootData;
                                          	rootData << "Root";
                                          	rootItem = new TreeItemBase(rootData);
                                          	setupModelData(data.split(QString("\n")), rootItem);
                                          }
                                          
                                          TreeModelBase::TreeModelBase(const QList<QVariant> &columnsData, QObject *parent)
                                          	: QAbstractItemModel(parent)
                                          {
                                          	rootItem = new TreeItemBase(columnsData);
                                          }
                                          
                                          int TreeModelBase::columnCount(const QModelIndex &parent) const
                                          {
                                          	if (parent.isValid())
                                          		return static_cast<TreeItemBase*>(parent.internalPointer())->columnCount();
                                          	return rootItem->columnCount();
                                          }
                                          
                                          QVariant TreeModelBase::data(const QModelIndex &index, int role) const
                                          {
                                          	if (!index.isValid()) return QVariant();
                                          
                                          	TreeItemBase *item = static_cast<TreeItemBase*>(index.internalPointer());
                                          	if (role == Qt::DisplayRole)
                                          		return item->data(index.column());
                                              if (role == Qt::ToolTipRole)
                                          		return item->getToolTip();
                                          	if (item->isCheckable() && role == Qt::CheckStateRole)
                                          		return item->getCheckState();	
                                          	return QVariant();
                                          }
                                          
                                          bool TreeModelBase::setData(const QModelIndex &index, const QVariant &value, int role)
                                          {
                                          	if (!index.isValid()) return false;
                                          	TreeItemBase *item = static_cast<TreeItemBase*>(index.internalPointer());
                                          	bool isUpdated = true;
                                          	if (role == Qt::DisplayRole)
                                          	{
                                          		QList<QVariant> data;
                                          		data << value;
                                          		item->setItemData(data);
                                          	}
                                          	else if (role == Qt::ToolTipRole)
                                          		item->setToolTip(value.toString());
                                          	else if (role == Qt::CheckStateRole)
                                          	{	//	If role requested is the CheckStateRole.
                                          		item->setCheckState((Qt::CheckState)value.toInt());
                                          		layoutChanged();
                                          	}
                                          	else
                                          		isUpdated = false;
                                          
                                          	if (isUpdated == true)
                                          	{
                                          		// Emit a refresh signal.
                                          		QModelIndex par = parent(index);
                                          		QModelIndex topLeft = this->index(0, 0, par);
                                          		int rc = rowCount(par);
                                          		int cc = columnCount(par);
                                          		QModelIndex bottomRight = this->index(rc - 1, cc - 1, par);
                                          		emit dataChanged(topLeft, bottomRight);
                                              }
                                          	return isUpdated;
                                          }
                                          
                                          Qt::ItemFlags TreeModelBase::flags(const QModelIndex &index) const
                                          {
                                          	if (!index.isValid()) return 0;
                                          	TreeItemBase *item = static_cast<TreeItemBase*>(index.internalPointer());
                                          	return item->getFlags();
                                          }
                                          
                                          QVariant TreeModelBase::headerData(int section, Qt::Orientation orientation, int role) const
                                          {
                                          	if (orientation == Qt::Horizontal && role == Qt::DisplayRole)
                                          		return rootItem->data(section);
                                          	return QVariant();
                                          }
                                          
                                          QModelIndex TreeModelBase::index(int row, int column, const QModelIndex &parent) const
                                          {
                                          	if (!hasIndex(row, column, parent))	return QModelIndex();
                                          
                                          	TreeItemBase *parentItem;
                                          	if (!parent.isValid())
                                          		parentItem = rootItem;
                                          	else
                                          		parentItem = static_cast<TreeItemBase*>(parent.internalPointer());
                                          
                                          	TreeItemBase *childItem = parentItem->childAt(row);
                                          	if (childItem)
                                          		return createIndex(row, column, childItem);
                                          	return QModelIndex();
                                          }
                                          
                                          QModelIndex TreeModelBase::parent(const QModelIndex &index) const
                                          {
                                          	if (!index.isValid())return QModelIndex();
                                          
                                          	TreeItemBase *childItem = static_cast<TreeItemBase*>(index.internalPointer());
                                          	TreeItemBase *parentItem = childItem->parent();
                                          	if (parentItem == rootItem)
                                          		return QModelIndex();
                                          	return createIndex(parentItem->row(), 0, parentItem);
                                          }
                                          
                                          int TreeModelBase::rowCount(const QModelIndex &parent) const
                                          {
                                          	TreeItemBase *parentItem;
                                          	if (parent.column() > 0) return 0;
                                          
                                          	if (!parent.isValid())
                                          		parentItem = rootItem;
                                          	else
                                          		parentItem = static_cast<TreeItemBase*>(parent.internalPointer());
                                          	return parentItem->childCount();
                                          }
                                          
                                          QModelIndex TreeModelBase::getIndex(const TreeItemBase *pNode, int column) const
                                          {
                                          	QModelIndex nodeIndex;
                                          	// ...
                                          	return nodeIndex;
                                          }
                                          
                                          // Insert new child to the node
                                          void TreeModelBase::insertChild(TreeItemBase *parent,	TreeItemBase *child, bool notify, int row)
                                          {
                                          	TreeItemBase *parentItem =  parent ? parent : rootItem;
                                          	if(!notify)
                                          	{
                                          		parentItem->insertChild(child, row);
                                          		return;
                                          	}
                                          
                                          	QModelIndex parentIndex = getIndex(parentItem);
                                          	if(row == -1)
                                          		row = parentItem->childCount();
                                          
                                          	beginInsertRows(parentIndex, row, row);	
                                          	parentItem->insertChild(child,row);
                                          	endInsertRows();
                                          	layoutChanged();
                                          }
                                          
                                          TreeItemBase* TreeModelBase::getItem(const QModelIndex &index) const
                                          {
                                          	return item = (index.isValid()) ? static_cast<TreeItemBase*>(index.internalPointer()):NULL;
                                          }
                                          
                                          void TreeModelBase::clearChildren(const QModelIndex &parent)
                                          {
                                          	TreeItemBase *parentItem = parent.isValid() ? static_cast<TreeItemBase*>(parent.internalPointer()) : rootItem;
                                          	int rows = parentItem->childCount();
                                          	if(rows > 0)
                                          	{
                                          		beginRemoveRows(parent, 0, rows - 1);
                                          		parentItem->removeChildren();
                                          		endRemoveRows();
                                          	}
                                          	layoutChanged();
                                          }
                                          
                                          void TreeModelBase::resetModel()
                                          {
                                          	beginResetModel();
                                          	rootItem->removeChildren();
                                          	endResetModel();
                                          }
                                          
                                          void TreeModelBase::resetModel(const QList<QVariant> &columnsData)
                                          {
                                          	beginResetModel();
                                          	rootItem->removeChildren();
                                          	delete rootItem;
                                          	rootItem = new TreeItemBase(columnsData);
                                          	endResetModel();
                                          }
                                          
                                          void TreeModelBase::updateModel()
                                          {
                                          	layoutChanged();
                                          }
                                          
                                          class Tree
                                          {
                                          	Q_OBJECT
                                          public:
                                          	Tree(const QList<QVariant> &columnsData, QWidget *parent = nullptr);
                                          protected:
                                          	layout::GUI::TreeModelBase *m_pTreeViewModel = nullptr;
                                          	QTreeView *m_pTreeView = nullptr;
                                          	QList<QVariant> m_lstColumnNames;
                                          }; 
                                          
                                          Tree::Tree(const QList<QVariant> &columnsData, QWidget *parent /* = nullptr */)
                                          	: QFrame(parent)
                                          	, m_lstColumnNames(columnsData)
                                          {
                                          	setContentsMargins(0, 0, 0, 0);
                                          
                                          	auto mainLayout = new QVBoxLayout(this);
                                          	mainLayout->setContentsMargins(0, 0, 0, 0);
                                          
                                          	m_pTreeViewModel = TreeModelBase(m_lstColumnNames, this);
                                          
                                          	m_pTreeView = new QTreeView(this);
                                          	m_pTreeView->setUniformRowHeights(true);
                                          
                                          	m_pTreeView->setModel(m_pTreeViewModel);
                                          	connect(m_pTreeView->selectionModel(), &QItemSelectionModel::selectionChanged,
                                          		this, &Tree::onSelectionChanged);
                                          	mainLayout->addWidget(m_pTreeView);
                                          }
                                          
                                          class TreeItem : public TreeItemBase
                                          {
                                          public:
                                          	TreeItem(const QList<QVariant> &data, TreeItemBase *parent = 0, bool bCheckable = true)
                                          		: TreeItemBase(data, parent, bCheckable)
                                          	{
                                          	}
                                          	TreeItem(const QString data, TreeItemBase *parent = 0, bool bCheckable = true)
                                          		: TreeItemBase(data, parent, bCheckable)
                                          	{
                                          	}
                                              
                                          	void setExpanded(bool bExpanded)
                                          	{
                                          		m_bExpanded = bExpanded;
                                          	}
                                          
                                          	bool isExpanded() const
                                          	{
                                          		return m_bExpanded;
                                          	}
                                          
                                          	int childCount() const
                                          	{
                                          		return m_bExpanded ? 1 : TreeItemBase::childCount();
                                          	}
                                          
                                          private:
                                          	bool m_bExpanded = false;
                                          
                                          }; // class TreeItem
                                          
                                          class TreeModel : public TreeModelBase
                                          {
                                          public:
                                          	TreeModel(const QString &data, QObject *parent = 0)
                                          		: TreeModelBase(data, parent)
                                          	{
                                          	}
                                          
                                          	TreeModel(const QList<QVariant> &columnsData, QObject *parent = 0)
                                          		: TreeModelBase(columnsData, parent)
                                          	{
                                          	}
                                          
                                          	int rowCount(const QModelIndex &parent /* = QModelIndex() */) const override
                                          	{
                                          		auto pNode = dynamic_cast<TreeItem *>(getItem(parent));
                                          		if (!pNode) return 0;
                                          		return pNode->childCount();
                                          	}
                                          }; // class TreeModel
                                          
                                          class OtherTree : public Tree
                                          {
                                          public:
                                                  OtherTree(QWidget *parent = nullptr) : Tree(parent)
                                                  {
                                                         delete m_pTreeViewModel;
                                          	       m_pTreeViewModel = new TreeModel(getColumns(), this);
                                          	       m_pTreeView->setModel(m_pTreeViewModel);
                                                  }
                                                 void populateView()
                                          {
                                          	m_pTreeViewModel->resetModel(getColumns());
                                          
                                          	auto pRootNode = m_pTreeViewModel->getRootItem();
                                          	while (whatever)
                                          	{
                                          		QList<QVariant> rowData;
                                          		for (auto idx = 0; idx < getColumns().size(); ++idx)
                                          			rowData << QVariant();
                                          
                                          		rowData[0] = someString;
                                          		auto pNode = new TreeItem(rowData, pRootNode, false);
                                          		pNode->setExpanded(true);
                                          		m_pTreeViewModel->insertChild(pRootNode, pNode, true);
                                          	}
                                          }
                                          };
                                          

                                          with this code the view isn't populated. when i comment out the 3 lines in OtherTree constructor, the tree is populated but rows don't have expand icon.

                                          1 Reply Last reply
                                          0

                                          2/20

                                          30 May 2019, 12:51

                                          topic:navigator.unread, 18
                                          • Login

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