Неправильная высота форматированного текста (QTextDocument) в элементе, отображаемом пользовательским делегатом элемента [Qt]
У меня есть проблема с высотой текста QTextDocument в моем делегате элемента представлений дерева.
Мои методы paint() и sizeHint() практически одинаковы, но рассчитывают разную высоту текста (один и тот же текст).
Разница в высоте варьируется в зависимости от шрифта. Если все написано в одном размере, то высота верна, но если я использую разные размеры, высота не совпадает.
Я читал тему об использовании метрик шрифта или вычислении формы высоты шрифта paiter.boundingRect, но я не знаю, как использовать это в QTextDocument.
Я думал, что проблема со шрифтом, поэтому я изменил глобальный шрифт на один с кодом ниже. Это не помогло.
//in main():
QFont font("MS Shell Dlg 2",8.25,50);
font.setPointSizeF(8.25);
QApplication::setFont(font);
Мой код в моем пользовательском элементе Delegate:
QSize MyItemDelegate::sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const
{
QStyleOptionViewItem options = option;
initStyleOption(&options, index);
int scrollBarrWidth = -2;
if(scrollBarVisible){
scrollBarrWidth = 10; //options.widget->style()->pixelMetric(QStyle::PM_ScrollBarExtent);
}
int checkboxWidth = 0;
if(checkboxesForConferenceActive){
checkboxWidth = 18;
}
QRect rectLeft(checkboxWidth,0,26,26);
QRect rectRight((options.widget->rect().right()-30-scrollBarrWidth),0,26,26);
QRect rectCenter((rectLeft.right()+5),-2,(options.widget->rect().width()-(rectLeft.width()+rectRight.width()+scrollBarrWidth+checkboxWidth+8+4)),26);
QRect boundingRect;
QString nameText(index.data(Qt::UserRole).toString());
QString extNoText(index.data(Qt::UserRole+1).toString());
QString phoneText(index.data(Qt::UserRole+100).toString());
QTextDocument textDoc;
textDoc.setDefaultFont(options.font);
textDoc.setTextWidth(rectCenter.width());
textDoc.setDocumentMargin(0);
QTextCursor textCursor(&textDoc);
QString wholeText("");
QImage statusIcon(*icoChooser->choseCustomStateImageForSubscriber(index.data(Qt::UserRole+12).toInt()));
bool wczytajfote = !statusIcon.isNull();
wholeText.append("<b>");
wholeText.append(nameText);
wholeText.append("</b>");
textCursor.insertHtml(wholeText);
if(wczytajfote){
textCursor.movePosition(QTextCursor::EndOfLine, QTextCursor::MoveAnchor);
textCursor.insertImage(statusIcon.scaledToWidth(12));
textCursor.movePosition(QTextCursor::End, QTextCursor::MoveAnchor);
} else {
textCursor.insertHtml(" ");
}
wholeText.clear();
if(!extNoText.isEmpty()){
wholeText.append("<font color = #005c99>");
wholeText.append(QString(" ("+extNoText+") "));
wholeText.append("</font>");
wholeText.append("<br><font style=\"font-size:10px; color: #6d6d78\">");
wholeText.append(index.data(Qt::UserRole+4).toString());
wholeText.append("</font>");
textCursor.insertHtml(wholeText);
if(textDoc.idealWidth() < rectCenter.width() ){
QRect clip(0,0,textDoc.idealWidth(), textDoc.size().height());
return QSize(textDoc.idealWidth(), textDoc.size().height()+4);
} else {
QRect clip(0,0,textDoc.idealWidth(), textDoc.size().height());
return QSize(textDoc.idealWidth(), textDoc.size().height()+4);
}
} else {
wholeText.append("<br>");
wholeText.append("<font size = 2 color = #005c99>");
wholeText.append(QString(" ("+phoneText+") "));
wholeText.append("</font>");
textCursor.insertHtml(wholeText);
QRect clip(0,0,textDoc.idealWidth(), textDoc.size().height());
return QSize(textDoc.idealWidth(), textDoc.size().height()+6);
}
}
и метод рисования практически точно такой же.
void MyItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
QStyleOptionViewItem options = option;
initStyleOption(&options, index);
painter->save();
painter->setRenderHint(QPainter::Antialiasing, true);
painter->setRenderHint(QPainter::SmoothPixmapTransform, true);
painter->setRenderHint(QPainter::TextAntialiasing, true);
options.text = "";
int scrollBarrWidth = -2;
if(scrollBarVisible){
scrollBarrWidth = 10; //options.widget->style()->pixelMetric(QStyle::PM_ScrollBarExtent);
}
int checkboxWidth = 0;
if(checkboxesForConferenceActive){
checkboxWidth = 18;
}
QRect rectLeft(checkboxWidth,0,26,26);
QRect rectRight((options.widget->rect().right()-30-scrollBarrWidth),0,26,26); //obliczam na podstawie prostokąta, który jest przed nim i który ma dynamicznie ustawiane wymiary
QRect rectCenter((rectLeft.right()+5),-2,(options.widget->rect().width()-(rectLeft.width()+rectRight.width()+scrollBarrWidth+checkboxWidth+8+4)),26); //obliczam prostokąt na podstawie wcześniejszego prostokąta i prostokąta wymiarów okna
QRect boundingRect;
QString nameText(index.data(Qt::UserRole).toString());
QString extNoText(index.data(Qt::UserRole+1).toString());
QString phoneText(index.data(Qt::UserRole+100).toString());
painter->translate(options.widget->rect().left(), options.rect.top());
QTextDocument textDoc;
textDoc.setTextWidth(rectCenter.width());
QTextCursor textCursor(&textDoc);
QString wholeText("");
QImage statusIcon(*icoChooser->choseCustomStateImageForSubscriber(index.data(Qt::UserRole+12).toInt()));
bool wczytajfote = !statusIcon.isNull();
wholeText.append("<b>");
wholeText.append(nameText);
wholeText.append("</b>");
textCursor.insertHtml(wholeText);
if(wczytajfote){
textCursor.movePosition(QTextCursor::EndOfLine, QTextCursor::MoveAnchor);
textCursor.insertImage(statusIcon.scaledToWidth(12));
textCursor.movePosition(QTextCursor::End, QTextCursor::MoveAnchor);
} else {
textCursor.insertHtml(" ");
}
wholeText.clear();
if(!extNoText.isEmpty()){
wholeText.append("<font size = 2 color = #005c99>");
wholeText.append(QString(" ("+extNoText+") "));
wholeText.append("</font>");
wholeText.append("<br><font style=\"font-size:10px; color: #6d6d78\">");
wholeText.append(index.data(Qt::UserRole+4).toString());
wholeText.append("</font>");
} else {
wholeText.append("<br>");
wholeText.append("<font size = 2 color = #005c99>");
wholeText.append(QString(" ("+phoneText+") "));
wholeText.append("</font>");
}
textCursor.insertHtml(wholeText);
painter->translate(rectCenter.left(), rectCenter.top());
QRect clip(0,0,textDoc.size().width(), textDoc.size().height());
textDoc.drawContents(painter, clip);
painter->restore();
}
}
Текст в sizeHint используется для определения высоты элемента, поэтому теперь он выглядит следующим образом:
Я использую 64-битную версию Qt 5.7.1 MSVC 2015 для Windows, но проблема все та же на Ubuntu 16.04 с gcc.
1 ответ
(Опубликовано от имени автора)
Это оказалось моей ошибкой все время.
Следующая строка отвечает в sizeHint()
Метод отвечал:
textDoc.setDocumentMargin(0);