Solved disable the Icon (decoration role) of the QStandardItems on for certain QTreeView?
-
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? -
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); } }
-
Cheers,
It makes sense that it is the delegate and not the view directly that does the job!
Thanks -
@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; } };
-
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; } }
-
@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 -
@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.