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. Add more than text to TreeView delegates? (like an extra Icon, ...)
Forum Updated to NodeBB v4.3 + New Features

Add more than text to TreeView delegates? (like an extra Icon, ...)

Scheduled Pinned Locked Moved Solved QML and Qt Quick
9 Posts 3 Posters 4.1k Views 1 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.
  • hvoigtH Offline
    hvoigtH Offline
    hvoigt
    wrote on last edited by
    #1

    Hi,

    I am trying to use a TreeView and have multiple things in the delegate. E.g. in some rows I would like to put an Icon. But from the example it seems there is only styleData.value available. I used to do that with different roles on a ListView but AFAICS they are used for the columns in the TreeView. Implementing a method like

    QString getIcon(const QModelIndex &index);
    
    

    which returns me the Icon is a workaround, but then I loose the property binding. So when I update my Model I would have to trigger the update of the display manually right?

    Is there a better way to extra things like icons to the TreeView delegates?

    Thanks, Heiko

    p3c0P 1 Reply Last reply
    0
    • hvoigtH hvoigt

      Hi,

      I am trying to use a TreeView and have multiple things in the delegate. E.g. in some rows I would like to put an Icon. But from the example it seems there is only styleData.value available. I used to do that with different roles on a ListView but AFAICS they are used for the columns in the TreeView. Implementing a method like

      QString getIcon(const QModelIndex &index);
      
      

      which returns me the Icon is a workaround, but then I loose the property binding. So when I update my Model I would have to trigger the update of the display manually right?

      Is there a better way to extra things like icons to the TreeView delegates?

      Thanks, Heiko

      p3c0P Offline
      p3c0P Offline
      p3c0
      Moderators
      wrote on last edited by p3c0
      #2

      Hi @hvoigt and Welcome,
      If I understood you correctly, you can use an Image component inside the delegate to set the icon ?

      157

      1 Reply Last reply
      0
      • C Offline
        C Offline
        cheezus
        wrote on last edited by cheezus
        #3

        You need to do a combination of things:

        1. You'll need a custom model (trust me, I've tried to use built-in stuff and it's good for the basics only)
        2. Set custom roles (see roleNames())

        Then your TableViewColumn will have a delegate with a role of (say) "compositeData" which you can then use for loading your image.

        Something like:

        TableViewColumn {
           role: "compositeData"
           delegate: Image{source: styleData.value.iconUrl} // Text{text: styleData.value.text}
        }
        
        ...
        
        QHash<int,QString> roleNames() const {
           QHash<int,QString> ret;
        
          ret[Qt::UserRole] = "compositeData"
        
          return ret;
        }
        
        QVariant data(...) {
          if(role == Qt::UserRole)
            return QVariantMap(...)
        }
        
        1 Reply Last reply
        0
        • hvoigtH Offline
          hvoigtH Offline
          hvoigt
          wrote on last edited by
          #4

          First of all: Thanks for all the quick replies.

          @p3c0: Hi, thanks for the welcome :) My question was more geared towards how to transport which icon should be drawn from the model (c++) to QML.

          @cheezus: So if I understand correctly I should implement a QAbstractItemModel and use that to return a QVariantMap in the data method. Is there any good example how to assemble the parent child stuff for the TreeView? At the moment I am using the QStandardItemModel since that is what I found in some example. I just searched and found this:

          http://doc.qt.io/qt-5/qtwidgets-itemviews-simpletreemodel-example.html

          If I setup the model like there I should be able to use it with the TreeView in QML right?

          C p3c0P 2 Replies Last reply
          0
          • hvoigtH hvoigt

            First of all: Thanks for all the quick replies.

            @p3c0: Hi, thanks for the welcome :) My question was more geared towards how to transport which icon should be drawn from the model (c++) to QML.

            @cheezus: So if I understand correctly I should implement a QAbstractItemModel and use that to return a QVariantMap in the data method. Is there any good example how to assemble the parent child stuff for the TreeView? At the moment I am using the QStandardItemModel since that is what I found in some example. I just searched and found this:

            http://doc.qt.io/qt-5/qtwidgets-itemviews-simpletreemodel-example.html

            If I setup the model like there I should be able to use it with the TreeView in QML right?

            C Offline
            C Offline
            cheezus
            wrote on last edited by
            #5

            @hvoigt Yep. I use the following:

            #ifndef TREEMODEL_HPP
            #define TREEMODEL_HPP
            
            #include <QAbstractItemModel>
            #include <memory>
            #include <vector>
            
            template <typename T>
            class TreeModel : public QAbstractItemModel {
            public:
              explicit TreeModel(QObject * parent=0):QAbstractItemModel(parent){}
            
              void reset() {
                beginResetModel();
                updateRootNodes();
                endResetModel();
              }
            
            protected:
              void
              updateRootNodes() {
                m_rootNodes = getRootNodes();
              }
              struct Node;
              using NodeVec = std::vector<std::unique_ptr<Node>>;
            
              struct Node {
                Node(std::shared_ptr<T> const & value,
                     Node*parent,int row):
                  value(value),
                  parent(parent),
                  row(row){}
            
                std::shared_ptr<T> value;
                Node * parent = nullptr;
                int row = -1;
                NodeVec children;
              };
            
              virtual
              NodeVec
              getRootNodes() = 0;
            
            private:
              std::vector<std::unique_ptr<Node>> m_rootNodes;
            
            protected:
              QModelIndex index(int row, int column, QModelIndex const & parent = QModelIndex()) const override;
              QModelIndex parent(QModelIndex const & index) const override;
              int rowCount(QModelIndex const & parent) const override;
            };
            
            #include "TreeModel.ipp"
            
            #endif // TREEMODEL_HPP
            
            // TreeModel.ipp
            template<typename T>
            QModelIndex
            TreeModel<T>::index(int row, int column, QModelIndex const & parent) const {
              if(!parent.isValid())
                return createIndex(row,column,m_rootNodes[row].get());
              else {
                auto parentNode = reinterpret_cast<Node*>(parent.internalPointer());
                return createIndex(row,column,parentNode->children[row].get());
              }
            }
            
            template<typename T>
            QModelIndex
            TreeModel<T>::parent(QModelIndex const & index) const {
              if(!index.isValid())
                return QModelIndex();
              auto node = reinterpret_cast<Node*>(index.internalPointer());
              if(!node->parent)
                return QModelIndex();
              else
                return createIndex(node->parent->row,0,node->parent);
            }
            
            template<typename T>
            int
            TreeModel<T>::rowCount(QModelIndex const & parent) const {
              if(!parent.isValid())
                return m_rootNodes.size();
              auto node = reinterpret_cast<Node*>(parent.internalPointer());
              return node->children.size();
            }
            
            1 Reply Last reply
            0
            • hvoigtH hvoigt

              First of all: Thanks for all the quick replies.

              @p3c0: Hi, thanks for the welcome :) My question was more geared towards how to transport which icon should be drawn from the model (c++) to QML.

              @cheezus: So if I understand correctly I should implement a QAbstractItemModel and use that to return a QVariantMap in the data method. Is there any good example how to assemble the parent child stuff for the TreeView? At the moment I am using the QStandardItemModel since that is what I found in some example. I just searched and found this:

              http://doc.qt.io/qt-5/qtwidgets-itemviews-simpletreemodel-example.html

              If I setup the model like there I should be able to use it with the TreeView in QML right?

              p3c0P Offline
              p3c0P Offline
              p3c0
              Moderators
              wrote on last edited by
              #6

              @hvoigt

              To return an image from QAbstractItemModel you can convert it to base64 and return a QString and to decode it on QML side something like this should work:

              Image {
                  source: "data:image/png;base64," + model.imagedata
              }
              

              If I setup the model like there I should be able to use it with the TreeView in QML right?

              Yes. Just make sure you re-implement roleNames.
              https://forum.qt.io/topic/56497/request-treeview-c-model-to-qml-example
              https://forum.qt.io/topic/56653/example-of-correctly-operating-c-model-with-qml-treeview/
              https://forum.qt.io/topic/56099/solved-new-treeview-does-not-connect-to-c-model

              157

              1 Reply Last reply
              0
              • hvoigtH Offline
                hvoigtH Offline
                hvoigt
                wrote on last edited by
                #7

                Got it. Its working for me now. Marked as solved.

                @cheezus: The bit with returning the QVariantMap() from the data(...) method was what solved my question.

                @p3c0: Thanks for the links they helped to implement the QAbstractItemModel and avoid the seemingly common pitfalls as well. The bit with base64 encoding the icon is an interesting one. I am currently just using an Image Path from the resources. But that might come in handy sometime.

                Thanks a lot, this was awesome.

                1 Reply Last reply
                0
                • hvoigtH Offline
                  hvoigtH Offline
                  hvoigt
                  wrote on last edited by
                  #8

                  @cheezus @p3c0 FYI

                  Since the question how to implement a TreeView with a QAbstractItemModel seems to have been asked a few times I took the opportunity and adapted the "Simple Tree Model Example" to QML. You can find it on my GitHub:

                  https://github.com/hvoigt/qt-qml-treeview/tree/master

                  p3c0P 1 Reply Last reply
                  2
                  • hvoigtH hvoigt

                    @cheezus @p3c0 FYI

                    Since the question how to implement a TreeView with a QAbstractItemModel seems to have been asked a few times I took the opportunity and adapted the "Simple Tree Model Example" to QML. You can find it on my GitHub:

                    https://github.com/hvoigt/qt-qml-treeview/tree/master

                    p3c0P Offline
                    p3c0P Offline
                    p3c0
                    Moderators
                    wrote on last edited by
                    #9

                    @hvoigt Thank you for sharing :)

                    157

                    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