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. disable the Icon (decoration role) of the QStandardItems on for certain QTreeView?
Forum Update on Monday, May 27th 2025

disable the Icon (decoration role) of the QStandardItems on for certain QTreeView?

Scheduled Pinned Locked Moved Solved General and Desktop
7 Posts 2 Posters 2.4k 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.
  • mbruelM Offline
    mbruelM Offline
    mbruel
    wrote on last edited by
    #1

    Hello,
    I'm having a main View that display my Model with icons on my items and I'd like to display a part of it on another view but without the icons.
    Would this be possible?
    Could I tell the view to not go for the decoration?

    1 Reply Last reply
    0
    • VRoninV Offline
      VRoninV Offline
      VRonin
      wrote on last edited by VRonin
      #2

      It's not the view, it's the delegate but sure you can

      WARNING: wrong code, see below

      class NoIconDelegate : public QStyledItemDelegate{
      Q_OBJECT
      Q_DISABLE_COPY(NoIconDelegate)
      public:
      exclicit NoIconDelegate(QObject* parent=Q_NULLPTR) : QStyledItemDelegate(parent){}
      void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const Q_DECL_OVERRIDE{
       Q_ASSERT(index.isValid());
          QStyleOptionViewItem opt = option;
          initStyleOption(&opt, index);
      opt.icon = QIcon();
      opt.decorationSize=QSize(-1, -1);
      opt.features &= ~QStyleOptionViewItem::HasDecoration;
          QStyle *style = option.widget ? option.widget->style() : QApplication::style();
      style->drawControl(QStyle::CE_ItemViewItem, &opt, painter, option.widget);
      }
      }

      "La mort n'est rien, mais vivre vaincu et sans gloire, c'est mourir tous les jours"
      ~Napoleon Bonaparte

      On a crusade to banish setIndexWidget() from the holy land of Qt

      1 Reply Last reply
      1
      • mbruelM Offline
        mbruelM Offline
        mbruel
        wrote on last edited by
        #3

        Cheers,
        It makes sense that it is the delegate and not the view directly that does the job!
        Thanks

        VRoninV 1 Reply Last reply
        0
        • mbruelM mbruel

          Cheers,
          It makes sense that it is the delegate and not the view directly that does the job!
          Thanks

          VRoninV Offline
          VRoninV Offline
          VRonin
          wrote on last edited by
          #4

          @mbruel On second thought, this is much better, it is more effivcient and also impacts sizeHint:

          class NoIconDelegate : public QStyledItemDelegate{
              Q_OBJECT
              Q_DISABLE_COPY(NoIconDelegate)
          public:
              explicit NoIconDelegate(QObject* parent=Q_NULLPTR) : QStyledItemDelegate(parent){}
          protected:
              void initStyleOption(QStyleOptionViewItem *option, const QModelIndex &index) const Q_DECL_OVERRIDE
              {
                  QVariant value = index.data(Qt::FontRole);
                  if (value.isValid() && !value.isNull()) {
                      option->font = qvariant_cast<QFont>(value).resolve(option->font);
                      option->fontMetrics = QFontMetrics(option->font);
                  }
                  value = index.data(Qt::TextAlignmentRole);
                  if (value.isValid() && !value.isNull())
                      option->displayAlignment = Qt::Alignment(value.toInt());
                  value = index.data(Qt::ForegroundRole);
                  if (value.canConvert<QBrush>())
                      option->palette.setBrush(QPalette::Text, qvariant_cast<QBrush>(value));
                  option->index = index;
                  value = index.data(Qt::CheckStateRole);
                  if (value.isValid() && !value.isNull()) {
                      option->features |= QStyleOptionViewItem::HasCheckIndicator;
                      option->checkState = static_cast<Qt::CheckState>(value.toInt());
                  }
                  value = index.data(Qt::DisplayRole);
                  if (value.isValid() && !value.isNull()) {
                      option->features |= QStyleOptionViewItem::HasDisplay;
                      option->text = displayText(value, option->locale);
                  }
                  option->backgroundBrush = qvariant_cast<QBrush>(index.data(Qt::BackgroundRole));
                  option->styleObject = 0;
              }
          };
          

          "La mort n'est rien, mais vivre vaincu et sans gloire, c'est mourir tous les jours"
          ~Napoleon Bonaparte

          On a crusade to banish setIndexWidget() from the holy land of Qt

          mbruelM 1 Reply Last reply
          3
          • VRoninV VRonin

            @mbruel On second thought, this is much better, it is more effivcient and also impacts sizeHint:

            class NoIconDelegate : public QStyledItemDelegate{
                Q_OBJECT
                Q_DISABLE_COPY(NoIconDelegate)
            public:
                explicit NoIconDelegate(QObject* parent=Q_NULLPTR) : QStyledItemDelegate(parent){}
            protected:
                void initStyleOption(QStyleOptionViewItem *option, const QModelIndex &index) const Q_DECL_OVERRIDE
                {
                    QVariant value = index.data(Qt::FontRole);
                    if (value.isValid() && !value.isNull()) {
                        option->font = qvariant_cast<QFont>(value).resolve(option->font);
                        option->fontMetrics = QFontMetrics(option->font);
                    }
                    value = index.data(Qt::TextAlignmentRole);
                    if (value.isValid() && !value.isNull())
                        option->displayAlignment = Qt::Alignment(value.toInt());
                    value = index.data(Qt::ForegroundRole);
                    if (value.canConvert<QBrush>())
                        option->palette.setBrush(QPalette::Text, qvariant_cast<QBrush>(value));
                    option->index = index;
                    value = index.data(Qt::CheckStateRole);
                    if (value.isValid() && !value.isNull()) {
                        option->features |= QStyleOptionViewItem::HasCheckIndicator;
                        option->checkState = static_cast<Qt::CheckState>(value.toInt());
                    }
                    value = index.data(Qt::DisplayRole);
                    if (value.isValid() && !value.isNull()) {
                        option->features |= QStyleOptionViewItem::HasDisplay;
                        option->text = displayText(value, option->locale);
                    }
                    option->backgroundBrush = qvariant_cast<QBrush>(index.data(Qt::BackgroundRole));
                    option->styleObject = 0;
                }
            };
            
            mbruelM Offline
            mbruelM Offline
            mbruel
            wrote on last edited by
            #5

            @VRonin

            cool to use directly the initStyleOption method :)
            I'm not sure why you explore so many Roles, this seems to do the job perfectly:

            void NoIconTreeItemDelegate::initStyleOption(QStyleOptionViewItem *option, const QModelIndex &index) const
            {
                QStyledItemDelegate::initStyleOption(option, index);
                option->icon           = QIcon();
                option->decorationSize = QSize(-1, -1);
                option->features      &= ~QStyleOptionViewItem::HasDecoration;
            }
            

            Personnaly I wish to only let the icons for my Root elements so here is my implementation:

            void NoIconTreeItemDelegate::initStyleOption(QStyleOptionViewItem *option, const QModelIndex &index) const
            {
                QStyledItemDelegate::initStyleOption(option, index);
                TreeItem *item = static_cast<const TreeProxyModel*>(index.model())->itemFromIndex(index);
                if (item && !static_cast<TreeItem*>(item)->isRootItem())
                {
                    option->icon           = QIcon();
                    option->decorationSize = QSize(-1, -1);
                    option->features      &= ~QStyleOptionViewItem::HasDecoration;
                }
            }
            
            VRoninV 1 Reply Last reply
            0
            • mbruelM mbruel

              @VRonin

              cool to use directly the initStyleOption method :)
              I'm not sure why you explore so many Roles, this seems to do the job perfectly:

              void NoIconTreeItemDelegate::initStyleOption(QStyleOptionViewItem *option, const QModelIndex &index) const
              {
                  QStyledItemDelegate::initStyleOption(option, index);
                  option->icon           = QIcon();
                  option->decorationSize = QSize(-1, -1);
                  option->features      &= ~QStyleOptionViewItem::HasDecoration;
              }
              

              Personnaly I wish to only let the icons for my Root elements so here is my implementation:

              void NoIconTreeItemDelegate::initStyleOption(QStyleOptionViewItem *option, const QModelIndex &index) const
              {
                  QStyledItemDelegate::initStyleOption(option, index);
                  TreeItem *item = static_cast<const TreeProxyModel*>(index.model())->itemFromIndex(index);
                  if (item && !static_cast<TreeItem*>(item)->isRootItem())
                  {
                      option->icon           = QIcon();
                      option->decorationSize = QSize(-1, -1);
                      option->features      &= ~QStyleOptionViewItem::HasDecoration;
                  }
              }
              
              VRoninV Offline
              VRoninV Offline
              VRonin
              wrote on last edited by
              #6

              @mbruel said in disable the Icon (decoration role) of the QStandardItems on for certain QTreeView?:

              I'm not sure why you explore so many Roles

              I just copy-pasted the body of QStyledItemDelegate::initStyleOption and removed the part that had to do with the decoration role.

              TreeItem *item = static_cast<const TreeProxyModel*>(index.model())->itemFromIndex(index);
                  if (item && !static_cast<TreeItem*>(item)->isRootItem())
              

              Using model-specific stuff inside the delegate is bad design. that whole snippet can be replaced with if(!index.parent().isValid()) and be compatible with all models

              "La mort n'est rien, mais vivre vaincu et sans gloire, c'est mourir tous les jours"
              ~Napoleon Bonaparte

              On a crusade to banish setIndexWidget() from the holy land of Qt

              mbruelM 1 Reply Last reply
              2
              • VRoninV VRonin

                @mbruel said in disable the Icon (decoration role) of the QStandardItems on for certain QTreeView?:

                I'm not sure why you explore so many Roles

                I just copy-pasted the body of QStyledItemDelegate::initStyleOption and removed the part that had to do with the decoration role.

                TreeItem *item = static_cast<const TreeProxyModel*>(index.model())->itemFromIndex(index);
                    if (item && !static_cast<TreeItem*>(item)->isRootItem())
                

                Using model-specific stuff inside the delegate is bad design. that whole snippet can be replaced with if(!index.parent().isValid()) and be compatible with all models

                mbruelM Offline
                mbruelM Offline
                mbruel
                wrote on last edited by mbruel
                #7

                @VRonin said in disable the Icon (decoration role) of the QStandardItems on for certain QTreeView?:

                Using model-specific stuff inside the delegate is bad design. that whole snippet can be replaced with if(!index.parent().isValid()) and be compatible with all models

                Yeah I know but my delegate is completely specialized to the need of my App.

                static_cast<TreeItem*>(item)->isRootItem()
                

                is not telling me if the item the root of TreeModel but rather if I should display the item bigger.
                I could have several types of Items that I wish to display bigger in my main TreeView. In the other ones where I'll use this delegate with no icon, I will just display the Icon only for those types without making it bigger and not display the icons for the "standard" other items

                @VRonin said in disable the Icon (decoration role) of the QStandardItems on for certain QTreeView?:

                I just copy-pasted the body of QStyledItemDelegate::initStyleOption and removed the part that had to do with the decoration role.

                Ah ok I see. I find it more clear to use the main method and then just override the decoration part.

                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