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

  • 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

  • Moderators

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

  • 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(...)

  • 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:

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

  • @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 {
      explicit TreeModel(QObject * parent=0):QAbstractItemModel(parent){}
      void reset() {
      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):
        std::shared_ptr<T> value;
        Node * parent = nullptr;
        int row = -1;
        NodeVec children;
      getRootNodes() = 0;
      std::vector<std::unique_ptr<Node>> m_rootNodes;
      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>
    TreeModel<T>::index(int row, int column, QModelIndex const & parent) const {
        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>
    TreeModel<T>::parent(QModelIndex const & index) const {
        return QModelIndex();
      auto node = reinterpret_cast<Node*>(index.internalPointer());
        return QModelIndex();
        return createIndex(node->parent->row,0,node->parent);
    template<typename T>
    TreeModel<T>::rowCount(QModelIndex const & parent) const {
        return m_rootNodes.size();
      auto node = reinterpret_cast<Node*>(parent.internalPointer());
      return node->children.size();

  • Moderators


    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.

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

  • @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:

  • Moderators

    @hvoigt Thank you for sharing :)

Log in to reply

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.