Qt自定义委托中的多行文本

时间:2012-02-24 15:15:10

标签: c++ ruby qt

我有一个派生自QStyleOptionViewItem的自定义委托,它试图在paint方法中绘制多行(wordwrap)一长行文本。在做了一些搜索和Qt doc阅读之后,我看起来我需要使用QTextLayout来完成这样的任务,下面是我仍然将文本放在一行中的代码,任何有关如何围绕QStyleOptionViewItem长度包装线的提示传入?谢谢!

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. 我没有为每一行设定位置。
  3. 这是我在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
    

1 个答案:

答案 0 :(得分:6)

我必须做一段时间同样的任务。 虽然我使用简单的QPainter::drwText,但我遇到了这个问题。

要进行自动换行,您应该:

  • 禁用uniformRowHeight视图属性。
  • 正确处理sizeHint。默认情况下,此函数返回0,您应该覆盖它以返回项目数据的Qt::SizeHint角色。

  • 但您还应为Qt::SizeHint角色设置正确的值。您可以使用QFontMetrics::boundingRect来计算sizeHint,但在计算sizeHint和绘制项目时,应确保使用相同的字体。在Windows 7我遇到了问题,QStandardItem的字体与QListView的字体不一致。

    请注意,每次请求时都从头开始计算sizeHint是个坏主意,因为它的效果非常慢。