I haven't played with my application for a while, now I came back to it and to sizeHint(). Below is my current implementation, which provides may be not perfect, but very good results.
There was some questions above regarding parent(). Ideally QAbstractItemDelegate do not need to know about QAbstractItemView, but in my case I have to set the view as a parent of the delegate because I need the width of the view to determine the height.
{
QString str
= index.
data().
toString().
trimmed();
QRectF boundingRect
= fontMetrics.
boundingRect(str
);
int width = view->viewport()->width() - 6;
int times = 0;
while (words.size() > 0) {
times++;
qreal lineWidth = 0;
bool enoughSpace = true;
do {
qreal wordWidth = fontMetrics.width(word);
if (wordWidth + lineWidth < width) {
lineWidth += wordWidth;
lineWidth
+= fontMetrics.
width(QChar(' '));
words.removeFirst();
} else
enoughSpace = false;
} while (enoughSpace && words.size() > 0);
}
return QSize(width, boundingRect.
height() * times
- times
+ 1);
}
void PartOfSpeechItemDelegate
::paint(QPainter *painter,
{
QRect rect
(option.
rect.
topLeft(), option.
rect.
bottomRight());
if (option.
state & QStyle::State_Selected) painter->fillRect(rect, option.palette.highlight());
painter->save();
painter
->setPen
(QPen(Qt
::gray));
painter->drawLine(rect.topLeft(), rect.topRight());
painter->restore();
rect.setLeft(rect.left() + 4);
rect.setTop(rect.top() + 2);
rect.setRight(rect.right() - 2);
painter->drawText(rect, Qt::TextWordWrap , index.data().toString());
}
QSize PartOfSpeechItemDelegate::sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const
{
QAbstractItemView *view = dynamic_cast<QAbstractItemView*>(parent());
QFontMetricsF fontMetrics(view->fontMetrics());
QString str = index.data().toString().trimmed();
QStringList words = str.split(QChar(' '));
QRectF boundingRect = fontMetrics.boundingRect(str);
int width = view->viewport()->width() - 6;
int times = 0;
while (words.size() > 0) {
times++;
qreal lineWidth = 0;
bool enoughSpace = true;
do {
QString word = words.first();
qreal wordWidth = fontMetrics.width(word);
if (wordWidth + lineWidth < width) {
lineWidth += wordWidth;
lineWidth += fontMetrics.width(QChar(' '));
words.removeFirst();
} else
enoughSpace = false;
} while (enoughSpace && words.size() > 0);
}
return QSize(width, boundingRect.height() * times - times + 1);
}
void PartOfSpeechItemDelegate::paint(QPainter *painter,
const QStyleOptionViewItem &option, const QModelIndex &index) const
{
QRect rect(option.rect.topLeft(), option.rect.bottomRight());
if (option.state & QStyle::State_Selected)
painter->fillRect(rect, option.palette.highlight());
painter->save();
painter->setPen(QPen(Qt::gray));
painter->drawLine(rect.topLeft(), rect.topRight());
painter->restore();
rect.setLeft(rect.left() + 4);
rect.setTop(rect.top() + 2);
rect.setRight(rect.right() - 2);
painter->drawText(rect, Qt::TextWordWrap , index.data().toString());
}
To copy to clipboard, switch view to plain text mode
My view:
void PartOfSpeechItemView
::resizeEvent(QResizeEvent *resizeEvent
) {
reset();
}
void PartOfSpeechItemView::resizeEvent(QResizeEvent *resizeEvent)
{
reset();
QListView::resizeEvent(resizeEvent);
}
To copy to clipboard, switch view to plain text mode
See the attachment how it looks like.
serega.
Bookmarks