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