Многострочный текст Qt в пользовательском делегате - PullRequest
2 голосов
/ 24 февраля 2012

У меня есть пользовательский делегат, полученный из QStyleOptionViewItem, который пытается нарисовать многострочную (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. Тестовая строка I представляет собой одно слово, состоящее из 200 символов, и по умолчанию QTextLayout выполняет перенос слов. Поэтому я должен явно вызвать QTextLayout :: setWrapMode () для переноса этого теста.
  2. Я не устанавливаю позицию для каждой строки.

Это мой метод рисования в Ruby:

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 Ответ

6 голосов
/ 24 февраля 2012

Я должен был сделать то же самое на некоторое время.Хотя я использовал простой QPainter::drwText, я столкнулся с этой проблемой.

Чтобы обеспечить перенос слов, вам необходимо:

  • отключить uniformRowHeight свойство представления.
  • handle sizeHint правильно.По умолчанию эта функция возвращает 0, вы должны переопределить ее, чтобы вернуть Qt::SizeHint роль данных элемента.

  • Но вы также должны установить правильное значение для роли Qt::SizeHint.Вы можете использовать QFontMetrics::boundingRect для вычисления sizeHint, но вы должны убедиться, что вы используете тот же шрифт при расчете sizeHint и при рисовании элемента.На Windows 7 у меня возникла проблема, что шрифт QStandardItem не совпадал с шрифтом QListView.

    Обратите внимание, что неправильно вычислять sizeHint с нуля при каждом запросе, потому что он работает очень медленно.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...