1
votes

I am using QStyledItemDelegate to style the items in my QTreeView.

The roots of my treeview are not decorated. It's just a simple tree with relation similar to the one below:

ColorBook1
    Color1
    Color2
ColorBook2
    Color3

The parent and child are styled differently and selection on parent is disabled.

I want to customise the selection behaviour in the child nodes so that the selection rectangle around the child would cover the entire row and not the text child alone.

Current Behaviour:

enter image description here

Desired Behaviour:

enter image description here

Is there any way to extend the selection rectangle like this using QStyledItemDelegate? I tried adjusting the rect in QStyleOptionViewItem parameter of QStyledItemDelegate::paint. But that moved the child node text to the left. I want to keep the text node at the same place but only the selection rectangle has to be adjusted to the left. So just like drawing text and pixmaps in the paint method is there a way to draw the selection rectangle as well(, using the default selection rect color)?

The paint method of my StyledItemDelegate is as follows:

I am using the following code in the QStyledItemDelegate::paint method:

void paint( QPainter * inPainter, const  QStyleOptionViewItem & inOption, const QModelIndex & inIndex ) const
  {
   if( inIndex.data( Qt::UserRole ) == ColorInfoType::kColorBook )
   {
      QFont font = inPainter->font();
      font.setWeight( QFont::Bold );
      font.setPointSize( 8 );
      inPainter->setFont( font );
      inPainter->drawText
         (
            inOption.rect.adjusted( 5,0,0,0 ),
            inIndex.data( Qt::DisplayRole ).toString(),
            QTextOption( Qt::AlignVCenter | Qt::AlignLeft )
         );
   }
   else
   {
      //To Do: draw the selection rect after adjusting the size.
      // Draw the Color Name text
      QStyledItemDelegate::paint( inPainter, inOption, inIndex );
   }
  }
1

1 Answers

2
votes

You can paint it yourself. Use option.palette.brush(QPalette::Highlight) to get the highlight color.

In this snippet I just paint the blank area manually. I also changed the color, but you don't have to do that.

void StyleDel::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
    if(option.state.testFlag(QStyle::State_Selected))
    {
        QStyleOptionViewItem newOption = option;
        newOption.state = option.state & (~QStyle::State_HasFocus);
        QBrush brush = option.palette.brush(QPalette::Highlight);
        brush.setColor(QColor(150,0,0,100));

        newOption.palette.setBrush(QPalette::Highlight, brush);
        QRect s_rect = newOption.rect; //we use this rect to define the blank area
        s_rect.setLeft(0); // starts from 0
        s_rect.setRight(newOption.rect.left()); //ends where the default rect starts
        painter->fillRect(s_rect, newOption.palette.brush(QPalette::Highlight));
        QStyledItemDelegate::paint(painter, newOption, index);
        return;
    }
    QStyledItemDelegate::paint(painter, option, index);
}