Как рисовать различные фоны с помощью QStyledItemDelegate?
Задача :
- у меня есть
QTreeViewобъект иQStandardItemModelв качестве модели для просмотра виджета; - для некоторых элементов я установил данные с помощью метода
setData, чтобы разделить их с параметром; - поэтому мне нужно нарисовать другой фон пиксельное изображение для
QStandardItemэлементов, которые имеют значок и некоторые текстовые данные; - и не хотят перерисовать все объекты items, я имею в виду значок и текст. Просто измените фон.
Во-первых, я был думая, что:
- я мог бы установить таблицы стилей CSS в
Qt Designerдля объекта с 2 различными фоновыми изображениями, ноQStandardItemне имеетsetPropertyметод...
Пример:
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;
}
- Затем я создал свой собственный делегат, унаследованный от класса
QStyledItemDelegate, и метод reimplement paint, но я не могу просто изменить фон, потому что QStyledItemDelegate::paint( painter, opt, index ); код будет перерисовывать мой drawPixmap...Пример:
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 );
}
Итак, я застрял...
2 ответов:
Вот мой трюк:
Часть таблицы стилей
Designer: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; }Делегат переопределил
paint()Метод: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(); } }Результирующий
QTreeViewВид:
Имеют хороший день! :)
PS: нет необходимости перерисовывать иконки, текст, выделение...
Метод paint делегата-это все или ничего, поэтому вы не сможете смешать свой фон с реализацией по умолчанию.
Однако, если вы достаточно компетентны, чтобы даже подумать о написании пользовательского делегата, у вас не должно возникнуть проблем с реализацией такого, который может нарисовать ваш фон плюс значок и текст.

Comments