2016-02-14 33 views
1

A QTreeView在自定義QStyledItemDelegate::paint方法的幫助下呈現。目的是向節點添加圖形元素,例如,在項目文本週圍繪製(並填充)一個框。樹項目可能有複選框,或者沒有。重新實現QStyledItemDelegate :: paint - 如何獲取子元素的座標?

下面的Ruby代碼實現了目標,除了我無法獲得文本元素的座標。經驗偏移量(x = 29; y = 4)可用作解決方法。方法super在文本框的頂部繪製文本。

  • 我怎樣才能獲得文本元素的座標?
  • 這是正確的做法,在所有的,或者我必須使用的drawTextdrawControl而不是調用父類油漆方法嗎?在那種情況下,你如何控制子元素的佈局?

(這個問題是不是紅寶石具體的含C++,歡迎答案。)

class ItemDelegate < Qt::StyledItemDelegate 

    def paint(painter, option, index) 

    text  = index.data.toString 
    bg_color = Qt::Color.new(Qt::yellow) 
    fg_color = Qt::Color.new(Qt::black) 
    offset = Qt::Point.new(29,4) 

    painter.save 
    painter.translate(option.rect.topLeft + offset) 

    recti = Qt::Rect.new(0, 0, option.rect.width, option.rect.height) 
    rectf = Qt::RectF.new(recti) 

    margin  = 4 
    bounding = painter.boundingRect(rectf, Qt::AlignLeft, text) 
    tbox  = Qt::RectF.new(Qt::PointF.new(-margin,0), bounding.size) 
    tbox.width += 2*margin 

    painter.fillRect(tbox, bg_color) 
    painter.drawRect(tbox) 
    painter.restore 

    super 
    end 
end 


編輯:請找self-contained example here in this Gist

回答

2

我在C++中遇到了同樣的問題。不幸的是,option.rect。*屬性的解決方法似乎是找到文本座標的唯一方法。

這裏我委託的paint方法:

void ThumbnailDelegate::paint(QPainter *p_painter, const QStyleOptionViewItem &p_option, const QModelIndex &p_index) const 
{ 
    if(p_index.isValid()) 
    { 
     const QAbstractItemModel* l_model = p_index.model(); 
     QPen l_text_pen(Qt::darkGray); 

     QBrush l_brush(Qt::black, Qt::SolidPattern); 

     /** background rect **/ 
     QPen l_pen; 
     l_pen.setStyle(Qt::SolidLine); 
     l_pen.setWidth(4); 
     l_pen.setBrush(Qt::lightGray); 
     l_pen.setCapStyle(Qt::RoundCap); 
     l_pen.setJoinStyle(Qt::RoundJoin); 

     p_painter->setPen(l_pen); 

     QRect l_border_rect; 
     l_border_rect.setX(p_option.rect.x() + 5); 
     l_border_rect.setY(p_option.rect.y() + 5); 
     l_border_rect.setWidth(p_option.rect.width() - 16); 
     l_border_rect.setHeight(p_option.rect.height() - 16); 

     QPainterPath l_rounded_rect; 
     l_rounded_rect.addRect(QRectF(l_border_rect)); 
     p_painter->setClipPath(l_rounded_rect); 

     /** background color for hovered items **/ 
     p_painter->fillPath(l_rounded_rect, l_brush); 
     p_painter->drawPath(l_rounded_rect); 

     /** image **/ 
     QPixmap l_pixmap = bytearrayToPixmap(l_model->data(p_index, ImageRole).toByteArray()).scaled(150, 150, Qt::KeepAspectRatio); 

     QRect l_img_rect = l_border_rect; 

     int l_img_x = (l_img_rect.width()/2 - l_pixmap.width()/2)+l_img_rect.x(); 

     l_img_rect.setX(l_img_x); 
     l_img_rect.setY(l_img_rect.y() + 12); 
     l_img_rect.setWidth(l_pixmap.width()); 
     l_img_rect.setHeight(l_pixmap.height()); 
     p_painter->drawPixmap(l_img_rect, l_pixmap); 

     /** label **/ 
     QRect l_txt_rect = p_option.rect; 
     l_txt_rect.setX(l_border_rect.x()+5); 
     l_txt_rect.setY(l_border_rect.y() + l_border_rect.height() -20); 
     l_txt_rect.setHeight(20); 
     l_txt_rect.setWidth(l_txt_rect.width()-20); 

     QFont l_font; 
     l_font.setBold(true); 
     l_font.setPixelSize(12); 
     p_painter->setFont(l_font); 
     p_painter->setPen(l_text_pen); 

     QString l_text = l_model->data(p_index, TextRole).toString(); 
     p_painter->drawText(l_txt_rect, Qt::ElideRight|Qt::AlignHCenter, l_text); 
    } 
    else 
    { 
     qWarning() << "ThumbnailDelegate::paint() Invalid index!"; 
    } 
} 

我不是熟練的Ruby,但,你可以看到,我使用drawPath,drawPixmap和的drawText。

下面是結果:

enter image description here

我覺得這是更好地避免超調用油漆,因爲它應該被Qt自動完成,並在用戶界面上的生命週期你可能碰壞。

相關問題