HowTo draw different backgrounds with QStyledItemDelegate?

qstyleditemdelegate, qt, qt4

Solution

Here is my trick:

The `Designer`'s stylesheet part:

QTreeView#treeView
{
    border: none;
    background-color:#f0f0f1;
}   

QTreeView#treeView::item,
QTreeView#treeView::branch
{
    height: 25px;
    border: none;
    color: #564f5b;
}

QTreeView#treeView::item:selected,
QTreeView#treeView::branch:selected
{
    border-bottom: none;
    color: #ffffff;    
    background-image: url(:/backgrounds/images/backgrounds/kontragents_row_selection.png);
    background-position: top left;  

}

QTreeView#treeView::item:selected:!active,
QTreeView#treeView::branch:selected:!active
{
    color: #ffffff;
}

Delegate reimplemented `paint()` method:

void paint( QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index ) const
 {
      QStyleOptionViewItemV4 opt = option; // Для обхода QTBUG-4310
      opt.state &= ~QStyle::State_HasFocus; // Чтобы не рисовался прямоугольник фокуса

      QBrush brush = opt.backgroundBrush;
      brush.setTexture( QPixmap( index.data( SORT_ROLE ).toBool()
           ? BACKGROUND_HIGH_PRIORITY
           : BACKGROUND_STANDARD ) );

      // FILL BACKGROUND     
      painter->save();
      painter->fillRect( opt.rect, brush );
      painter->restore();

      // DRAW ICON & TEXT
      QStyledItemDelegate::paint( painter, opt, index );

      // IF ( CHILD ) THEN PAINT OVER ONLY! BRANCH RECT
      bool isIndexParent = !index.parent().isValid();
      if( !isIndexParent )
      {
           QRect rect( 0, opt.rect.y(), 20, opt.rect.height() );

           if( opt.state & QStyle::State_Selected )
           {
                brush.setTexture( QPixmap( BACKGROUND_SELECTED ) );
           }

           painter->save();
           painter->fillRect( rect, brush );
           painter->restore();
      }
 }

Resulting `QTreeView` view:

Have a nice day! :)

PS: no need redrawing icons, text, selection...

Problem

Problem: - I have `QTreeView` object, and a `QStandardItemModel` as model to view widget; - For some item's I have set data with `setData` method to split them with a parameter; - So I need to draw different background pixmap for `QStandardItem` items, which are with icon's and some text data; - And don't want to redraw all the items objects, I mean icon and text. Just change background. First, I was thinking that: - I could set CSS stylesheets in `Qt Designer` for the object with 2 different background pictures, BUT `QStandardItem` doesn't have `setProperty` method... Example: ``` QTreeView#treeView::item[ROLE="AAA"], QTreeView#treeView::branch[ROLE="AAA"] { height: 25px; border: none; color: #564f5b; background-image: url(:/backgrounds/images/row1.png); background-position: top left; } QTreeView#treeView::item[ROLE="BBB"], QTreeView#treeView::branch[ROLE="BBB"] { height: 25px; border: none; color: #564f5b; background-image: url(:/backgrounds/images/row2.png); background-position: top left; } ``` - then I created my own delegate, inherited from `QStyledItemDelegate` class, and reimplement `paint` method, BUT I can't just change background, because `QStyledItemDelegate::paint( painter, opt, index );` code will overdraw my `drawPixmap`... Example: ``` QStyleOptionViewItemV4 opt = option; // Для обхода QTBUG-4310 opt.state &= ~QStyle::State_HasFocus; // Чтобы не рисовался прямоугольник фокуса QStyledItemDelegate::paint( painter, opt, index ); // HERE I WANT TO CHANGE BACKGROUND (DEFAULT IS ALREADY SET IN DESIGNER WITH ABOVE CODE) if( index.data( SORT_ROLE ).toBool() ) { const QPixmap pixmap( ":/backgrounds/images/backgrounds/contractor_row__high_priority.png" ); painter->drawPixmap( option.rect, pixmap, pixmap.rect() ); QStyledItemDelegate::paint( painter, opt, index ); } ``` So I'm stuck...

Original source