3

问题

  • 我有QTreeView对象,还有一个QStandardItemModel作为模型来查看小部件;
  • 对于某些项目,我使用setData方法设置数据以使用参数拆分它们;
  • 所以我需要为项目绘制不同的背景像素图QStandardItem,其中包含图标和一些文本数据;
  • 并且不想重绘所有项目对象,我的意思是图标和文本。只是改变背景。

首先,我在想:

  • Qt Designer我可以为具有 2 个不同背景图片的对象设置 CSS 样式表, 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类继承并重新实现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 );
}

所以我被困住了...

4

2 回答 2

6

这是我的窍门:

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:无需重绘图标、文字、选择...

于 2012-05-28T12:23:31.177 回答
1

委托的绘制方法是全有或全无,因此您将无法将背景与默认实现混合。

但是,如果您有足够的能力甚至可以考虑编写自定义委托,那么实现一个可以绘制背景以及图标和文本的委托应该没有问题。

于 2012-05-25T16:31:52.007 回答