【问题标题】:HowTo draw different backgrounds with QStyledItemDelegate?如何使用 QStyledItemDelegate 绘制不同的背景?
【发布时间】:2012-05-25 16:16:06
【问题描述】:

问题

  • 我有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 ); 代码会透支我的@987654332 @...

例子:

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 );
}

所以我被卡住了......

【问题讨论】:

    标签: qt qt4 qstyleditemdelegate


    【解决方案1】:

    这是我的窍门:

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

    【讨论】:

      【解决方案2】:

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

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

      【讨论】:

      • 我想要的只是不要用图标和文本重绘行项目,因为所以我必须找到图标和文本的正确位置,并调整图标大小......我认为这不是最好的方式...
      • 根据您的要求,您别无选择。 QStyledItemDelegate::paint(....) flood 的默认实现用 option.palette.base() 颜色填充 option.rect,所以你不能使用它。
      • 话虽如此,传递给委托的QStyleOptionViewItem 来自视图 - 所以也许您可以使用 CSS 为 QTreeView 提供新的基色?
      • 我必须更改 PNG 图像,而不仅仅是背景颜色。就目前而言,我认为这个技巧可能会有所帮助QStyleOptionViewItemV4 opt = option; if( isNewPng ) { QBrush brush = opt.backgroundBrush; brush.setTexture( QPixmap( NEW_PNG ) ); opt.backgroundBrush = brush; } QStyledItemDelegate::paint( painter, opt, index ); ...
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-02-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多