I have a QTreeView
with more than one column (like a table). Columns in the tree have a fixed size. I need to resize row heights and use multi-lined text like QTableView::resizeRowsToContents
.
How can I do this?
I've tried using a custom QStyledItemDelegate
with reimplemented sizeHint
, but I don't know how to calculate multiline text block height with known width.
Using QStyledItemDelegate
is the right approach. In your sizeHint
function, you can use the style options text with the QFontMetrics class:
QSize MyItemDelegate::sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const override {
QSize baseSize = this->QStyledItemDelegate::sizeHint(option, index);
baseSize.setHeight(10000);//something very high, or the maximum height of your text block
QFontMetrics metrics(option.font);
QRect outRect = metrics.boundingRect(QRect(QPoint(0, 0), baseSize), Qt::AlignLeft, option.text);
baseSize.setHeight(outRect.height());
return baseSize;
}
Note: Right now I cannot test this, but it should work. You may have to tweak the call to metrics.boundingRect
if the output does not fit your needs
EDIT:
It seems the sizeHint
will be only called once to create the initial layout, but not after resizing the columns.
A final Idea could be to override the QAbstractItemModel::data
function to return the desired size using Qt::SizeHintRole
. You could either add it to your existing model or provide a proxy-model to do this:
QSize MyModel::data(const QModelIndex &index, int role) const override {
switch(role) {
//...
case Qt::SizeHintRole:
{
QSize baseSize(getFixedWidth(index.column()), baseSize.setHeight(10000));//something very high, or the maximum height of your text block
QFontMetrics metrics(this->data(index, Qt::FontRole).value<QFont>());
QRect outRect = metrics.boundingRect(QRect(QPoint(0, 0), baseSize), Qt::AlignLeft, this->data(index, Qt::DisplayRole)));
baseSize.setHeight(outRect.height());
return baseSize;
}
//...
}
}
Important: Everytime your view gets resized, you will have to emit the dataChanged
signal for all those items. getFixedWidth
is something you will have to implement to return the current width of the given column.