2012-02-24 45 views
2

我有一個從QStyleOptionViewItem派生的自定義委託,它試圖在繪製方法中繪製多行(wordwrap)長文本行。在做了一些搜索和Qt文檔閱讀之後,我看起來像我需要使用QTextLayout來完成這樣的任務,下面是我已經將代碼放在一行中的代碼,關於如何圍繞QStyleOptionViewItem通過了?謝謝!!Qt自定義代理中的多行文本

void Delegate::paint(QPainter *painter, 
        const QStyleOptionViewItem &option, 
        const QModelIndex &index) const 
{ 
    painter->save(); 

    painter->translate(option.rect.topLeft()); 

    QString title = index.data(Qt::DisplayRole).toString(); 
    QTextLayout * layout = new QTextLayout(title, QApplication::font()); 

    layout->beginLayout(); 
    QTextLine line = layout->createLine(); 
    while (line.isValid()) { 
    line.setLineWidth(option.rect.width()); 
    line = layout->createLine(); 
    } 
layout->endLayout(); 
    layout->draw(painter, QPointF(0, 0)); 

    painter->restore(); 
} 

因爲我不能自己回答,所以我會在這裏發表我的發現。 我發現我的代碼夫婦的問題:

  1. 測試字符串我是一個字組成的200個字符,默認QTextLayout不換行。所以我必須爲該測試用例顯式調用QTextLayout :: setWrapMode()來包裝。
  2. 我並沒有爲每一行設置位置。

這是用Ruby我paint方法:

def paint painter, styleOptionViewItem, modelIndex 
    painter.save 
    painter.translate styleOptionViewItem.rect.top_left 

    marked_text = modelIndex.data(Qt::DisplayRole).value 
    font = Qt::Application::font() 
    text_layout = Qt::TextLayout.new marked_text 
    text_layout.setFont font 

    text_option = Qt::TextOption.new 
    text_option.setWrapMode(Qt::TextOption::WrapAtWordBoundaryOrAnywhere) 
    text_layout.setTextOption text_option 

    text_layout.beginLayout 
    fm = Qt::FontMetrics.new font 
    font_height = fm.height 
    i = 0 
    while i< LINE_LIMIT do 
    line = text_layout.createLine 
    break if (!line.isValid()) 
    line.setLineWidth(styleOptionViewItem.rect.width) 
    line.setPosition(Qt::PointF.new(0, font_height * i)) 
    i += 1 
    end 
    text_layout.endLayout 
    text_layout.draw painter, Qt::PointF.new(0, 0) 
    painter.restore 
end 
+0

此[PySide頁](http://www.pyside.org/docs/pyside/PySide/QtGui/QTextLayout.html)根據「具體實施方式」具有我試圖模仿的代碼。 – 2012-02-24 15:53:18

回答

6

我不得不一會兒做相同的任務。 雖然我用簡單的QPainter::drwText,但我碰到這個問題。

爲了使自動換行工作時,你應該:看

  • 禁用uniformRowHeight財產。
  • 正確處理sizeHint。默認情況下,此函數返回0,您應覆蓋它以返回項目數據的Qt::SizeHint角色。

  • 但是您還應該爲Qt::SizeHint角色設置正確的值。您可以使用QFontMetrics::boundingRect來計算sizeHint,但是在計算sizeHint和繪圖項目時,應確保使用相同的字體。在Windows 7我有一個問題,QStandardItem的字體不符合QListView的字體。

    請注意,每次請求時從頭開始計算sizeHint是個壞主意,因爲它的工作非常緩慢。