QTreeView:resizeRowsToContents 等效或如何在行中自动换行文本
QTreeView: resizeRowsToContents equivalent or how to word-wrap text in rows
我有一个包含多个列的 QTreeView
(例如 table)。树中的列具有固定大小。我需要调整行高并使用 QTableView::resizeRowsToContents
等多行文本。
我该怎么做?
我尝试使用自定义 QStyledItemDelegate
并重新实现 sizeHint
,但我不知道如何计算已知宽度的多行文本块高度。
使用QStyledItemDelegate
是正确的方法。在您的 sizeHint
函数中,您可以使用样式选项 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;
}
注意:现在我无法测试它,但它应该可以工作。如果输出不符合您的需要,您可能需要调整对 metrics.boundingRect
的调用
编辑:
sizeHint
似乎只会被调用一次来创建初始布局,但不会在调整列的大小后调用。
最终的想法可能是使用 Qt::SizeHintRole
将 QAbstractItemModel::data
函数覆盖为 return 所需的大小。您可以将其添加到现有模型或提供代理模型来执行此操作:
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;
}
//...
}
}
重要提示:每次调整视图大小时,您都必须为所有这些项目发出 dataChanged
信号。 getFixedWidth
是你必须实现的东西 return 给定列的当前宽度。
我有一个包含多个列的 QTreeView
(例如 table)。树中的列具有固定大小。我需要调整行高并使用 QTableView::resizeRowsToContents
等多行文本。
我该怎么做?
我尝试使用自定义 QStyledItemDelegate
并重新实现 sizeHint
,但我不知道如何计算已知宽度的多行文本块高度。
使用QStyledItemDelegate
是正确的方法。在您的 sizeHint
函数中,您可以使用样式选项 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;
}
注意:现在我无法测试它,但它应该可以工作。如果输出不符合您的需要,您可能需要调整对 metrics.boundingRect
的调用
编辑:
sizeHint
似乎只会被调用一次来创建初始布局,但不会在调整列的大小后调用。
最终的想法可能是使用 Qt::SizeHintRole
将 QAbstractItemModel::data
函数覆盖为 return 所需的大小。您可以将其添加到现有模型或提供代理模型来执行此操作:
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;
}
//...
}
}
重要提示:每次调整视图大小时,您都必须为所有这些项目发出 dataChanged
信号。 getFixedWidth
是你必须实现的东西 return 给定列的当前宽度。